tsJensen

A quest for software excellence...

Easy Debug Windows Service

I know this problem has been solved many times and written about many times, but every time I go to create a new Windows Service project, I end up re-researching how to debug and step through code in a Windows Service project in Visual Studio.

I've done it now, again, building my first real set of Windows Service projects in Visual Studio 2005 and this time I took the compiler directive approach. It's been done before, sure, and many have written about it, but for my own short term memory's sake, here's my solution.

Step One
Create the Windows Service project using the New Project wizard and the Windows Service template.

Step Two
Modify the nicely created program.cs file as follows:

using System;
using System.Collections.Generic;
using System.ServiceProcess;
using System.Text;

namespace YourNameSpace
{
#if (DEBUG)
   class Program
#else
   static class Program
#endif
   {
      /// 
      /// The main entry point for the application.
      /// 
#if (DEBUG)
      static void Main(string[] args)
#else
      static void Main()
#endif
      {
#if (DEBUG)
         ServiceRunner sr = new ServiceRunner();
         sr.Start(args);
         Console.WriteLine("Started... Hit enter to stop...");
         Console.ReadLine();
         sr.Stop();
#else
         ServiceBase[] ServicesToRun;
         ServicesToRun = new ServiceBase[] { new Service1() };
         ServiceBase.Run(ServicesToRun);
#endif
      }
   }
}

Step Three
Modify the Service1.cs file as follows:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;

namespace YourNameSpace
{
   public partial class Service1 : ServiceBase
   {
      private ServiceRunner serviceRunner = null;
      public Service1()
      {
         InitializeComponent();
         serviceRunner = new ServiceRunner();
      }

      protected override void OnStart(string[] args)
      {
         serviceRunner.Start(args);
      }

      protected override void OnStop()
      {
         serviceRunner.Stop();
      }
   }

   internal class ServiceRunner
   {
      public void Start(string[] args)
      {
         //TODO: Add code that will execute on start.
      }
      public void Stop()
      {
         //TODO: Add code that will execute on stop.
      }
   }
}

Step Four
Change the output type (in properties page of the project) to console application.

Now debug away!