Click here to Skip to main content
Email Password   helpLost your password?

Introduction

Normally, debugging a Windows service under Visual Studio .NET is painful. Windows services won't actually run directly within Visual Studio .NET, so the usual technique is to install and start the Windows service and then attach a debugger to it. An alternative approach is to pull the guts out of the service, stick it in a separate library, and then build some other app (e.g., a console app) to sit in front of it. This approach uses neither of those techniques.

When building a C# Windows Service project in Visual Studio, it will leave you with a class containing quite a few methods including a Main(), such as this:

// The main entry point for the process

static void Main()
{
    System.ServiceProcess.ServiceBase[] ServicesToRun;

    // More than one user Service may run within the same process. To add

    // another service to this process, change the following line to

    // create a second service object. For example,

    //

    // ServicesToRun = new 

    //      System.ServiceProcess.ServiceBase[] {new Service1(), 

    //      new MySecondUserService()};

    //


    ServicesToRun = new System.ServiceProcess.ServiceBase[] { new Service1() };
    System.ServiceProcess.ServiceBase.Run(ServicesToRun);
}

Obviously, it's the Main() above that ends up executing the service, and it's the Main() that this approach manipulates so that the Windows Service can be debugged directly within Visual Studio .NET.

Using the example above (and removing some of the comments), here's how:

// The main entry point for the process

static void Main()
{
#if (!DEBUG)
    System.ServiceProcess.ServiceBase[] ServicesToRun;
    ServicesToRun = new System.ServiceProcess.ServiceBase[] { new Service1() };
    System.ServiceProcess.ServiceBase.Run(ServicesToRun);
#else
    // Debug code: this allows the process to run as a non-service.

    // It will kick off the service start point, but never kill it.

    // Shut down the debugger to exit

    Service1 service = new Service1();
    service.<Your Service's Primary Method Here>();
    // Put a breakpoint on the following line to always catch
    // your service when it has finished its work
    System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
#endif 
}

It's crude, but effective (CBE - also known as Commander of the British Empire ;)). Run the service in debug mode to debug it, compile and install it as a release build, and it's a full and proper Windows service.

You may still wish to pull the guts out of your service into a separate library for unit testing. But this approach allows you to work with almost all of your service code as an actual service.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralI'm still not understanding something...
Ray Mitchell
13:57 23 Sep '09  
I'm afraid I'm too dense for this simple technique. I've seen this solution all over the net but what actually needs to be done still eludes me. Apparently I'm supposed to create an entirely new and unrelated service project and somehow link it to or merge it with the service I actually want to debug. The author mentions reading the entire article, but I couldn't find any more than just the short discussion and examples on the first page.
Generalanother way to create, debug, instal windows service....
GamePlanner
15:36 7 Apr '09  
I found another great way of creating, debugging and installing the windows service[^]
GeneralAwesome!
Jammer
5:41 27 Mar '09  
Gets my 5 ...


Generaltime saving and powerful!
thorleifs
8:56 20 Mar '09  
yes! simple things are nice.. time saving and powerful...

thorleifs

GeneralExtremely helpful .. Caught my admiration
hackrogenius
11:23 3 Mar '09  
yes simpler things are hell nice..time saving and powerful...

i actually loved thread sleeping thing which would catch Timers events ...
Nice example ...

--
ASif Ashraf
MCPD, MCAD.Net
Asif.Log@gmail | hotmail.com
92-306-4526526
Sr. dotNet & Flash Developer
Blu Media Works LHR PK

GeneralNiceness!
progrez
23:58 8 Jan '09  
OMG! That is soo nice! Saves a bunch of time when debugging services! Thanks man!
QuestionCan you use OnStop()???
keith shumway
9:25 13 Nov '08  
Using this Method of debugging a service is there a way from inside the debugger to call the OnStop() Method? I have used your method for debugging a service but am having issues in my Shutdown code and getting the debugger in there to help would be great.

Thanks,
AnswerRe: Can you use OnStop()???
Lee Humphries
11:32 13 Nov '08  
It depends on what your bug is.

If it's just a problem within the OnStop then change the call to sleep forever below with a call to your OnStop.

// Put a breakpoint on the following line to always catch
// your service when it has finished its work
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);

However if it's the actual calling of OnStop that seems to be the problem, then I'd suggest reading through some of the earlier comments as there are more than a few people who've taken this idea and gone even further with it.

I just love Koalas - they go great with Bacon.

GeneralRe: Can you use OnStop()???
keith shumway
13:01 13 Nov '08  
My problem is in the code that OnStop() executes (my code to shutdown the service). Since in debug it is not really a service (but an application per this article) I have no way to call OnStop() while in debug. Does that make my question clearer?
GeneralExcellent Tip..
Member 3978711
23:20 16 Oct '08  
I jus love it
GeneralNice!
Danie de Kock
3:12 1 Oct '08  
Thanks this Laugh saved me alot of time!
GeneralGood, but...
Andreas Saurwein Franci Gonçalves
8:53 30 Sep '08  
.. dont ever call SetServiceStatus() or RequestAdditionalTime() if not running under the service process or you earn exceptions.

To avoid them, create new overloads of them in your ServiceBase derived class like:

protected new void RequestAdditionalTime(Int32 nTime)
{
if(!Environment.UserInteractive)
base.RequestAdditionalTime(nTime);
}



Leon[^] - Enterprise Anti-Spam Server

GeneralGood job
The Ruler
23:57 18 Jul '08  
Very good job Lee. Thanks for an effective solution.

Thanks & Regards,

Viresh Shah

GeneralABS love it !!!
izmoto
2:44 2 Apr '08  
Kick ass sample.
love it absolutely. Its really helped me catch some nasty bug. Cool

void izmoto(char* szKwazi);

GeneralAnother way to do it
Einar Egilsson
8:14 15 Aug '07  
I recently wanted to do something similar. I wanted to be able to run my program as both a windows service and a standalone console application, and be able to debug it without the hassle of installing it as a service. I came up with a way to make it work, that doesn't include special builds, #DEBUG directives, command line parameters or anything like that. I just wrote down my solution at: http://tech.einaregilsson.com/2007/08/15/run-windows-service-as-a-console-program/
Hope it can be useful for someone Smile



GeneralRe: Another way to do it
nnm
13:34 28 Aug '07  
A simple approach to debug .NET service!

Thanks

nn coder
GeneralNICE, EXCELLENT!!!!
Balder1978-2
8:54 14 Aug '07  
Thank you so much, so easy! Smile

Best regards,
Christian

GeneralA Cleaner Way?
sstreaker
3:38 8 Jul '07  
I came up with what I think is a cleaner way to do this, perhaps you will agree:

Instead of using the #if compiler conditional to test for debug mode, which is perfect except for (as you mentioned) having to switch between Debug/Release mode all the time, you can use a command-line argument. Set the command line argument to "debugmode" or something simliar on the Debug tab in your project properties, then test for the existence of this argument in Main. Now when you run the project from Visual Studio, the command line arg will be set and you'll always run the non-service code; outside of Visual Studio, your app will run only as a Windows service.


// The main entry point for the process
static void Main(string[] args) {

if(args.Length > 0 && args[0] == "debugmode") {

// Debug code: this allows the process to run as a non-service.
// It will kick off the service start point, but never kill it.
// Shut down the debugger to exit
Service1 service = new Service1();
service.();
// Put a breakpoint on the following line to always catch
// your service when it has finished its work
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);

} else {

System.ServiceProcess.ServiceBase[] ServicesToRun;
ServicesToRun = new System.ServiceProcess.ServiceBase[] { new Service1() };
System.ServiceProcess.ServiceBase.Run(ServicesToRun);

}

}

GeneralRe: A Cleaner Way?
Lee Humphries
14:37 8 Jul '07  
Yep that would work - the only issue with it is the extra step to add the commandline argument (trivial) and of course the chance that you may release debug code as a service. With my one it really didn't behave well if you tried to run the debug version as a service - so you knew when you had screwed up and put out a debug build.
GeneralI dont get it [modified]
TEMoore
12:57 29 May '07  
I cannot get this work at all.

What is Service1 ?


-- modified at 18:04 Tuesday 29th May, 2007
GeneralRe: I dont get it
Lee Humphries
13:27 29 May '07  
If you're simply cutting and pasting from the article - then you won't get anywhere. You need to follow the instructions in the article and create a new C# Windows Service project in Visual Studio, once you've done that you'll be left with a service class called Service1. You would normally change this name to something more suitable and put in your current Service code.

The Service1 code itself would probably look like:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;

namespace WindowsService1
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}

protected override void OnStart(string[] args)
{
// TODO: Add code here to start your service.
}

protected override void OnStop()
{
// TODO: Add code here to perform any tear-down necessary to stop your service.
}
}
}

GeneralRe: I dont get it
TEMoore
6:21 30 May '07  
Well I have service that is running I am trying make changes to it and need to do debug. The item in the service is OnStart. Which does not work. Error message = No overload for method 'OnStart' takes '0' arguments


GeneralRe: I dont get it
Lee Humphries
17:12 30 May '07  
In which case I'd still recommend building a new service, making the changes I described and then transferring over that 'model' to your existing service. After that read through the comments below which discuss some options related to OnStart.
GeneralElegant Solution
John-Howard
9:16 15 May '07  
Nice Work, Thanks!

"Simplicity is the ultimate sophistication" - Leonardo Da Vinci

GeneralTimer event isn't called
Nicolas Stuardo
12:13 10 Apr '07  
Hello...

I have a Windows Service that in OnStart method set 2 timers that tick when determined time has elapsed.

I can debug OnStart method using your technique, but the timers never get called. Any way to do it?

Thanks


Last Updated 14 Aug 2006 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010