(As it so happens I literally just finished a windows service on a project of mine.)
I used a framework that is "in development" but so far has worked well. It's called Topshelf (n.b. it depends on StructureMap & log4net).
It handles all the messy stuff with Windows Services, such as dependencies, credentials and so on. Basically you create a configuration, sort of like this (more examples in the link):
var cfg = RunnerConfigurator.New(x =>
{
x.SetDisplayName("Timeout Service");
x.SetServiceName("mt_timeout");
x.ConfigureService<TestService>(c=>
{
c.WhenStarted(s => s.Start());
c.WhenStopped(s => s.Stop());
c.WhenPaused(s => { });
c.WhenContinued(s => { });
});
x.DoNotStartAutomatically();
// Multiple options available here, including prompt
x.RunAsLocalSystem();
x.DependsOn("ServiceName");
});
Runner.Host(cfg, args)
Apart from doing a lot of stuff for you, it has a two distinct advantages:
- the installer is built in, so you can
just run your "app.exe /install" and
it will install (without using the
.NET utility InstallService.exe -
part of the exe).
- you can run the app as a console app for debugging. This is a huge advantage over other methods such as Thread.Sleep at the beginning of your service to give enough time for debugger to attach (or options like this). The latter may cause you some headaches when you install the service, debug the app, dettach the debugger and try to uninstall the service. In some cases (when the app was left running, some rogue thread or so) the service will be marked for deletion, meaning you can't install a new version with the same name, but you can't remove the old one without a reboot.
(A last word: I cannot compare this two any other win service framework, because frankly so far I did it myself... kind of "not-invented-here" syndrome :| )
Hope that helps