Click here to Skip to main content
Licence CPOL
First Posted 18 Apr 2005
Views 276,151
Bookmarked 150 times

Debugging Windows Services under Visual Studio .NET

By | 14 Aug 2006 | Article
How to 'fudge' Windows Services code so that it can be debugged under Visual Studio .NET.

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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Lee Humphries

Founder
md8n
Australia Australia

Member

Follow on Twitter Follow on Twitter
If it ain't broke - that can be arranged.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralRe: Timer event isn't called PinmemberAnderson Imes3:07 18 Apr '07  
GeneralGreat piece of code Pinmemberjimcmt0:56 1 Mar '07  
GeneralGood stuff...and so easy Pinmembercraig.w14:50 7 Feb '07  
GeneralGood Job! Pinmemberrichan23:03 6 Jan '07  
JokeI stole your idea PinmemberAnderson Imes3:10 28 Dec '06  
GeneralRe: I stole your idea PinmemberLee Humphries11:09 28 Dec '06  
GeneralRe: I stole your idea PinmemberAnderson Imes12:57 28 Dec '06  
Hah! That'd be something.
 
The solution I came up with has a flaw though: it only tests the methods you implement on the service, not its ability to live in the Windows Services environment. At least accurately, anyway.
 
For example, if you (for some reason) didn't know you couldn't put UI code in a service without first checking "Allow Service to Interact with the Desktop" (a terrible practice anyway), then you wouldn't find this bug until you installed the service with installutil.exe and ran it from there. Similarly, you are going to have problems with calls to this.EventLog.Write* because the service won't be installed and therefore the event log won't have information for your service registered with it yet.
 
These kinds of issues come up no matter what solution you try. It's sad that they can't have special support in VS for debugging these things. Maybe in Orcas?

GeneralDEBUG switch PinmemberGnuconcepts3:38 17 Nov '06  
GeneralRe: DEBUG switch PinmemberLee Humphries14:29 19 Nov '06  
GeneralThank You Pinmemberzeineddine6:16 15 Sep '06  
GeneralVery nice! Pinmemberdave_ferreira6:18 22 Aug '06  
GeneralRe: Very nice! PinmemberLee Humphries14:55 22 Aug '06  
GeneralRe: Very nice! Pinmemberdave_ferreira15:01 22 Aug '06  
JokeRe: Very nice! PinmemberLee Humphries16:20 22 Aug '06  
GeneralRe: Very nice! Pinmemberdave_ferreira16:40 22 Aug '06  
JokeRe: Very nice! PinmemberLee Humphries16:49 22 Aug '06  
GeneralClever workaround! Pinmembermoriority511:05 11 Aug '06  
GeneralRe: Clever workaround! PinmemberLee Humphries11:21 13 Aug '06  
GeneralSolution to that PinmemberLeo Davidson2:18 15 Aug '06  
GeneralThanks - And Some Extra Stuff PinPopularmemberjriesen20:31 27 Jun '06  
GeneralRe: Thanks - And Some Extra Stuff PinmemberLee Humphries12:26 28 Jun '06  
GeneralBest article !!! PinmemberPhan Dung22:59 7 May '06  
GeneralWorks great Pinmemberpchelp10:34 25 Apr '06  
GeneralThanks PinmemberVicttim10:22 5 Apr '06  
QuestionHow about Pinmembernfoyt13:18 30 Mar '06  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120529.1 | Last Updated 14 Aug 2006
Article Copyright 2005 by Lee Humphries
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid