Use Topshelf To Make Windows Services..... It's Top Shelf!

This will be be a short post, and it's more of a public service announcement for something that's been out for a while; but Topshelf is so fantastic that it's worth giving it a mention, in case you haven't run into it yet.

If you're anything like me, when you have the need to create a Windows service to do some sort of background task, typically you just start off with a console application because it's super easy and super-easy to debug.  Then after you finish working on the logic, you do a bunch of Googling (or copy and pasting) to figure out how to make a service.  You also probably continue to have a way of running the code as a console application, for on-screen debug information and such.

Topshelf takes care of all of that for you.  With minimal code changes I was able to take my console application and convert it into a service.

Take a look for yourself.  Old code:

    static void Main(string[] args)



New code:

static void Main(string[] args)
            HostFactory.Run(x =>
                x.Service<Program>(s =>
                    s.ConstructUsing(p => new Program());
                    s.WhenStarted(p => p.StartMessagePump(););
                    s.WhenStopped(p => Log("Shutting Down"));

                x.SetDescription("Event Processor");
                x.SetDisplayName("Event Processor");


How easy was that?

Additional goodies include command line arguments that can be supplied to your application.  For instance, to install on the server, with a delayed start, I'd use the following command (in an admin console):

EventProcessor.exe install --delayed

It's that easy.  Topshelf is available as a Nuget package.  Next time you need to create a Windows service, give it a spin!

Further Notes

The following has nothing to do with Topshelf, but I thought you might find it useful anyway.  A Windows service must return control to the caller (the thing starting the service) in a timely fashion.  If you don't (as was the case with me, my service has a while(true) loop), you will get the following error:

error 1053 the service did not respond to the start or control request in a timely fashion


The easiest solution to this is to introduce a timer to your startup code and have the blocking code kick off after a short time passes.

private void Init()

            _timer.Elapsed += _timer_Elapsed;
            _timer.Enabled = true;

private void _timer_Elapsed(object sender, ElapsedEventArgs e)
        _timer.Enabled = false;

So if you landed on this page after Googling "error 1053"... you're welcome!




Add comment