Simplify Windows Service development with Topshelf

I accidentally discovered there is a Topshelf project which helps building Windows services. Here is the official way of doing this, by the way.

Just yesterday I went on to create a test Windows service (to host a quartz.net scheduler per se) and the overall experience with debugging was really below “okay”.

using System;  
using System.Threading;  
using Quartz;  
using Quartz.Impl;  
using ServiceStack.Text;

namespace QuartzTest  
{
    internal static class Program
    {
        public const string ListeningOn = "http://*:8002/";
        private static void Main()
        {
            IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
            var appHost = new AppHost(scheduler);
#if DEBUG
            try
            {
                scheduler.Start();
                appHost.Init();
                appHost.Start(ListeningOn);
                Thread.Sleep(Timeout.Infinite);
            }
            catch (Exception ex)
            {
                "ERROR: {0}: {1}".Print(ex.GetType().Name, ex.Message);
                throw;
            }
            finally
            {
                appHost.Stop();
                scheduler.Shutdown();
            }
#else
            ServiceBase[] servicesToRun =
            {
                new WpmSchedulerService(appHost, ListeningOn, scheduler)
            };
            ServiceBase.Run(servicesToRun);
#endif
        }
    }
}

You basically have to use #ifdef to have two discrete startup modes for both release and debug environments... and then you have to go and configure service installers and all that jazz with installutil.exe installation/uninstallation on every rebuild.

With Topshelf you can have neat initialization like this one which I borrowed from Quartz.Server sample

HostFactory.Run(x => {

      x.RunAsLocalSystem();

      x.SetDescription(Configuration.ServiceDescription);
      x.SetDisplayName(Configuration.ServiceDisplayName);
      x.SetServiceName(Configuration.ServiceName);

      x.Service(factory =>
                    {
                        QuartzServer server = new QuartzServer();
                        server.Initialize();
                        return server;
                    });
  });

Maybe I will have to revisit this post later and expand it with my actual experience with Topshelf, but so far it looks very promising alternative.