You are here
Home > Programming > Debugging Windows Services using an #if Directive

Debugging Windows Services using an #if Directive

Debugging Windows Services – I love writing them. In fact, to encompass a unit of functionality in a self contained bit of code is incredibly powerful. That is, if it is written correctly. I think it is something we as programmers take a bit for granted. One thing I know, is that debugging a Windows Service is one of the most painful things ever. Give it a try… Create a Windows Service in Visual Studio (I’m using Visual Studio Ultimate 2012), start it in debug mode and take a gander at the error message you get.

Debugging Windows Services

Debugging Windows Services

This week my colleague showed me an article he came across. The content of this article (Referenced at the end of this post) made me very excited. If you are creating a Windows Service, there is a way to get rid of the whole install-with-installutil.exe method when you want to debug your code. To illustrate this method, fire up Visual Studio and create a Windows Service.

Having a look in the Program.cs file, you will see the following code:

[sourcecode language=”csharp”]

static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}

[/sourcecode]

Now, all that my dummy Windows Service does is check if SQL Server is running. In the Service1.cs file, I have added the following method:

[sourcecode language=”csharp”]
public string IsServiceRunning()
{
string ServiceStatus = string.Empty;
ServiceController sc = new ServiceController("MSSQL$SQLSERVER");

try
{
switch (sc.Status)
{
case ServiceControllerStatus.Running:
return "Running";
case ServiceControllerStatus.Stopped:
return "Stopped";
case ServiceControllerStatus.Paused:
return "Paused";
case ServiceControllerStatus.StopPending:
return "Stopping";
case ServiceControllerStatus.StartPending:
return "Starting";
default:
return "Changing";
}
}
catch(Exception ex)
{
ServiceStatus = "error – " + ex.Message;
}
return ServiceStatus;
}
[/sourcecode]

The IsServiceRunning() method will usually be called from the OnStart() method of the service. But let’s say that the IsServiceRunning() method contains much more complex code that needs testing. You can test this method immediately without having to install the service first. Change your Program.cs file to look as follows:

[sourcecode language=”csharp”]
static void Main()
{
#if(!DEBUG)
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
#else
Service1 oService = new Service1();
oService.IsServiceRunning();
#endif
}
[/sourcecode]

The #if directive basically tells Visual Studio to run a different bit of code if we are debugging. Have a look at the screenshots below. If we select Start –> Release, the code that will be executed is live and the code that will not run is greyed out.

Debugging Windows Services

Change to Start –> Debug, and you will see that the code in the #else portion of the #if directive is now live, and the code after the #if is greyed out.

Debugging Windows Services

You can now start your Windows Service in Debug Mode and step into your IsServiceRunning() method directly and test it to your hearts content. Now isn’t that the neatest thing you have ever seen?

Original article by Tejas Vaishnav

Dirk Strauss
Dirk is a Software Developer and Microsoft MVP from South Africa. He loves all things Technology and is slightly addicted to Twitter and Jimi Hendrix. Apart from writing code, he also enjoys writing human readable articles. "I love sharing knowledge and connecting with people from around the world. It's the diversity that makes life so beautiful." Dirk feels very strongly that pizza is simply not complete without Tabasco, that you can never have too much garlic, and that cooking the perfect steak is an art he has yet to master.

Similar Articles

  • Dan

    Alternatively, you can detect if the debugger is attached.

    static void Main()
    {
    if (System.Diagnostics.Debugger.IsAttached)
    {
    Trace.WriteLine(“Starting as a application”);
    Service1 service = new Service1();
    service.IsServiceRunning();
    }
    else
    {
    Trace.WriteLine(“Starting as a service”);
    ServiceBase[] ServicesToRun = new ServiceBase[] { new ServiceFactory() };
    ServiceBase.Run(ServicesToRun);
    }
    }

    • Dirk Strauss

      Hi Dan

      Yes, you are quite right. Thank you for the great comment!

Top