Wednesday, September 19, 2012

Using TopShelf to create a Windows Service

As I blogged about on Monday, I am working on a project where I needed to create a Windows Service to automatically restore MS SQL ‘.bak’ Backup files to a SQL Server instance. While working on that project, I came across this blog post by developer extraordinaire Scott Hanselman. The purpose of his post was to talk about the free Visual Studio 2012 Express edition for Windows Desktop, (which incidentally, you should check out if you haven’t already) but in the post he mentioned TopShelf as being a great library for making Windows Services easier to write using .NET . After publishing my blog post Monday, my friend and co-worker Thad Smith also replied on Twitter asking if I had checked out TopShelf.

I had in fact looked at TopShelf, but got the code working for the traditional Windows Service first. The next morning though, first thing I went in and finally got the TopShelf version working as well. I wanted to post this as an addendum to the first post, showing how to achieve the same goal using TopShelf to create the service.

If you haven’t read my first post on the subject go back and check it out now, because the code is basically the same, and I want be covering most of it again. The biggest difference is in the Main() method where the TopShelf library comes into play for creating the Service as seen here:

Also, I have a Start() method that covers the same functionality (and is basically the same code) as the OnStart() method in the traditional service:

My App.config is exactly the same as from the traditional service, and the only other main difference is the installation process. For the Windows Service project, I actually created an installer project which generated a .msi installer, however for TopShelf, you simply launch cmd as Administrator and run the command NameOfService.exe install and similarly you uninstall with NameOfService.exe uninstall. Simple enough. My service started life as a Console Application as I was feeling my way around in the code, and it was much simpler to simply turn the Console app into a service using the TopShelf method, and using TopShelf you can create an application that can be run as both a service and a Console App.

Now, for sake of completeness, here is the full Program.cs for the TopShelf service:

Also, please note: In the Program.cs I have completed the functionality for generating my dbname variable from a period delimited Array generated from the full filename on disk.


  1. I've read that Topshelf works cross-platform, can you confirm that it works on say, OpenSUSE (or point me to a wiki somewhere)?

  2. I hadn't heard that, but interesting if it does. I will see what I can find out.

  3. Reference:
    There is some text that reads: "Cross-Platorm" and "Currently being used to host services on both Windows and Mono"
    Along with a link that currently does not go anywhere.
    If it's capable of running as a Linux daemon, then that's pretty cool!

  4. 2 years behind the times I know, but I've just come accross this blog and I can indeed confirm it works on mono running under linux.

    I'm currently writing a set of services using NancyFX, Topshelf and Stackexchange Redis and all work fine.