1

I have created a Windows Installer for a windows service with VS 2017. The windows service has a project installer and service installer class inside it. When I cancel the uninstallation process midway, the process removes the windows service but does not update data, so the next time I run the setup , I get the option to Repair or Uninstall the windows service. Attempting to uninstall the windows service now gives an error that "the specified service does not exist", and hence the uninstall process rolls back. Now the system is in a state where the service can neither be installed nor uninstalled. To be able to remove the service completely, it must be installed once again from the command line, so that it can be properly uninstalled. Is there a way around this issue? I thought of using the service install table to make sure that the service is properly removed even on cancel, but then I get the error that service is already installed when trying to install the service [The Project Installer/Service Installer classes do this installation, I think]

PhilDW
  • 19,260
  • 1
  • 14
  • 23

2 Answers2

1

First make sure that you've done all the custom action service installer nodes, in particular have the Commit and Rollback node custom actions populated. These custom actions all work together, so if you have missed one of them that could cause the problem. In theory, canceling the uninstall should have noted that the service is no longer installed, and it should be re-installed.

If that's not the issue, then it's probably a bug. The most useful thing you can do to fix it is to override base.Uninstall() in the installer class and add some code to check the service is actually installed before calling base.Uninstall().

Visual Studio setup projects are the only ones that use code to install services, and they are custom actions to call installer class methods. Everyone else uses the ServiceInstall and ServiceControl tables supplied by Windows Installer.

Some of the options you can use if you don't want to completely switch to another tool such as WiX are:

  1. The ServiceControl and ServiceInstall tables aren't too complicated if you know something about services. If you scroll down from here to the paragraph about Visual Studio and installing services there's an article and a program to help with that:

http://www.installsite.org/pages/en/msi/tips.htm

  1. You could dive into WiX enough to create a merge module that will install the services, together with any start/stop actions required. Then merge that merge module into your Visual Studio setup. No custom actions are required (and install classes are custom actions so you don't need them).
PhilDW
  • 19,260
  • 1
  • 14
  • 23
  • Thanks a lot PhilDW. I did both i. Add custom actions to rollback and commit, and ii. Added code to check for existence of service before calling base.Uninstall. That did the trick. – Sagar Kapadia May 22 '18 at 08:33
0

MSVS Installers & Custom Actions: You are using the Microsoft Visual Studio 2017 Installer Projects? They are very limited. The use of custom actions for service installation is one symptom of this. The use of custom actions in general is a very error prone approach (might be an over the top write-up), and for service installation it is almost never the right approach. Get rid of custom actions whenever you can and your deployment failure rate will drop.

Built-In Service Installation Features: You should use the built-in service installation features of Windows Installer (ServiceInstall and ServiceControl tables - which you seem familiar with), and there are a number of tools that can help you do this. Here are some alternative tools (free and commercial) that you can use. WiX does the job nicely, but does have a learning curve.


Service State: I would reboot in your case, to get rid of the service's current error state. It might be in some odd state pending deletion that could cause weird test results. I never take the time to investigate such issues properly, instead prefering to try and eliminate them by a simple reboot to get rid of the error state. Then do the deployment right with built-in features and that error state should never occur. A problem removed is ten problems solved? ( wishful thinking :-) ).


Stein Åsmul
  • 34,628
  • 23
  • 78
  • 140
  • Thanks Stein.Can I get code in the ProjectInstaller and ServiceInstaller classes to run without using custom actions? I need that to properly uregister the application on the server [I make a web service call at the time of uninstallation]. Or is there any other than the ProjectInstaller/ServiceInstaller classes [which force me to use custom actions] ]to run custom code on install or uninstall? – Sagar Kapadia May 21 '18 at 06:30
  • Custom actions (of various kinds - binaries, scripts, dlls, etc...) are the available constructs to run custom code during deployment. [Custom actions are error prone](https://stackoverflow.com/a/46179779/129130) - the leading cause of deployment failure. I am particularly skeptical to code which requires network access from within MSI setups - the whole technology was never designed with networking in mind (MSI is over 20 years old - back from the day of floppies). In silent mode the whole install runs in system context, and network access is then problematic. – Stein Åsmul May 21 '18 at 16:32