Installing a Windows Service without MSI
Recently I had to write a Windows service in C# and encountered an interesting issue: seems that, due to our setup, I was not allowed to use msi packages to install it.
This post doesn’t focus on writing Windows services, as there are numerous sources online that talk about this. For example you can take a look at this article on CodeProject: http://www.codeproject.com/KB/dotnet/simplewindowsservice.aspx
The interesting thing is that all articles on services end with installation through msi – you write the service installer class decorated with the RunInstaller attribute and use a custom action on the setup project that automatically takes care of running the installation code.
But, as I said, I couldn’t use such a setup project. After some more searching, I found another interesting article that suggested using the InstallUtil application that comes with .NET Framework: http://www.codeproject.com/KB/cs/DynWinServiceInstallUtil.aspx
Seems that the application does pretty much the same thing as a deployment through msi would do, namely it runs the required code in the RunInstaller class. But I was reluctant do depend on a batch file for deployment. Now considering that the RunInstaller attribute is implemented in the framework, I thought there also must be a class that interprets this attribute. Seems I was right: I found the AssemblyInstaller class in the System.Configuration.Install namespace.
The AssemblyInstaller constructor takes as argument an assembly and a set of command line options and provides the same methods available through msi deployment – Install, Commit, Rollback and Uninstall. More information on the AssemblyInstaller can be found on MSDN: http://msdn.microsoft.com/en-us/library/system.configuration.install.assemblyinstaller.aspx
I suggest this approach in case msi deployment is unavailable, the advantage over using a batch file being that it is completely independent of external applications (except the .NET Framework, of course), any custom deployment code can be added and you also get .NET exception handling for any errors that might occur.