Creating Windows Service quite often comes as natural choice when some long-term task needs to be done or, god forbid, you need something running while there is nobody to log on. Although services are useful, there are two things that annoy me and they are just too non-obvious to do. One is debugging services and another one is installing them.
For quite a while I’ve been using installutil.exe in order to install services. Since I am fan of being able to put things on system without actually installing them, that meant that I went through hoops to write C# code which will find installutil.exe in all it’s possible locations, under any combination of service packs and then to parse output once it gets executed.
I am not proud that it took me literally years to get idea to open installutil.exe in Reflector. And there, under whole glory, there was single function that does everything. And to make things even better parameters for this function are same as parameters for installutil.exe itself.
In order to install service, it is enough to pass name of executable (executing assembly in this example) and magic will happen:
ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
Uninstall is same story. Additional “unistall” (or “u”) flag is all it takes:
ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
Design of whole thing leaves lot to be desired. It just doesn’t feel like .NET - it feels like whole thing was pushed in after somebody noticed that there is no installer and there are only 2 hours before final version of .NET comes out.
One could get into refactoring whole thing out and making “proper” installer without too much effort. However, personally I will not do it. Although this function annoys me, I am also assured that Microsoft takes care of testing it and that it will work on every supported version of .NET Framework on every supported platform. Services are difficult enough without risking installation issues on some obscure combination.
Things that are not (badly) broken should not be fixed.
P.S. Not to forget, you need reference to System.Configuration.Install.dll in your program.