Easiest way to develop/debug a Windows service

18,473

Solution 1

Debugger.Break()  

:)

Solution 2

If you can handle a little C#, this is the way I do it.

Assuming you have a class MainService derived from ServiceBase with an onStart Method then, when not running inside the debugger, the service starts normally, otherwise the onStart is called manually which runs the code in console mode.

static void Main(string[] args)
{
       // If no command line arguments, then run as a service unless we are debugging it.
       if ( args.Length == 0) 
       {
            if (System.Diagnostics.Debugger.IsAttached)
            {
                 System.Diagnostics.Debugger.Break();
                 args = new string[] { "/NonService"} ;
            }
          else
                 args = new string[] { "/Service"} ;
       }

       string cmdLine = args[0].ToLower().Substring(1);
       Console.WriteLine("Starting Program with Cmdline : " + args[0]);
       switch (cmdLine)
       {
           case "service" :
               ServiceBase.Run(new MainService());
               break;

           case "nonservice" :
               MainService ms = new MainService();
               ms.OnStart(null);
               break;

         ...

         default :
            Console.Error.WriteLine("Unknown Command line Parameter");
            Console.Error.WriteLine("Supported options are /Install /Uninstall /Start /Stop /Status /Service and /NonService");
         }

Solution 3

Apart from use of Debugger.Break(), which several others have already mentioned, I write all my service code in a seperate assembly to the actual windows service project itself. I then also write a windows console app that calls the same service code. This lets me debug in the IDE just by setting the console app as the startup project.

The windows service project and the windows console application themselves literally do nothing except call the service "core" code, so the scope for defects due to the differences between the service and the console app are minimal.

Solution 4

When I develop a Windows service using .NET, I take advantage of unit tests plus TypeMock so that I can run the code of the service in a unit test, without having to attach to a running instance of the service. Other mocking frameworks you could look at include Rhino Mocks.

So my plan was to use MSTest to create the unit test project and test methods that run against my service, and any run-time dependencies would be handled by TypeMock, which would create mock objects for my service to use. So if my service was handling stuff to do with files, for example, then I could create a mock file, using TypeMock, and use that in my unit test to pass to the service.

In the past, I went through the pain of compiling the service, installing it, running it and attaching, etc. When I discovered mock frameworks, it was such a great feeling being able to test my code with a single click of a button from the Visual Studio IDE.

Give it a try.

Solution 5

Another way is to go to service1.designer.vb file, locate and "encapsulate" the following method code like this:

Shared Sub Main()
#If DEBUG Then
   Dim servicio As New Service1
   servicio.OnStart(Nothing)
   System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite)
#Else
   Dim ServicesToRun() As System.ServiceProcess.ServiceBase               'original code
   ServicesToRun = New System.ServiceProcess.ServiceBase() {New Service1} 'original code
   System.ServiceProcess.ServiceBase.Run(ServicesToRun)                   'original code
#End If

Hope this help for those programers with legacy code out there ;) Credits go to a fellow programmer, who teached it to me.

Share:
18,473
eugened
Author by

eugened

My name is Ryan McCauley, and I'm a database/reporting manager for a mid-size cable company. I spent a number of years as a .NET developer (mostly of the VB.NET variety), but now largely focus on T-SQL and the reporting with the Microsoft BI stack. On my own time, I build small apps to help get things done a little better, and have a couple posted at Codeplex: SQL Space Map - if you have some large SQL Server databases and you'd like a visual picture of which tables and indexes are taking up that space, it's the tool for you. SQL Server Contention Monitor - watches as may SQL Servers as you want and alerts you to blocked SPIDs, showing you the block tree (which process is blocking which, an what others are affected). It's still in a pretty alpha-ish phase, but it despite some instability at times, it gets the job done. Check them out and let me know what feedback you have!

Updated on June 19, 2022

Comments

  • eugened
    eugened almost 2 years

    I'm developing a Windows Service in VB.NET 2008, but I feel like I'm going to have an aneurysm. To debug the service, I've added a 15 second wait to the initialization code, which gives me time to start the service and attach the .NET debugger before anything happens, so I can hit breakpoints and such. I really miss "integrated" debugging with this type of workaround, and testing seems to be a huge pain.

    What's the best way to do "regular" debugging of a Windows Service that's in development? One option I'd considered was moving all of my logic to a DLL project, leaving only control logic in the service itself, and then creating a Forms project that essentially just had "start" and "stop" buttons on it, and called into the DLL to do everything else. This way, I can debug my code normally, and then just deploy the compiled service when the DLLs are ready.

    Does this make sense/annoy others? I'm open to any workarounds available. PB's suggestion here sounds like what I'm asking - has anybody used this approach?

  • eugened
    eugened almost 15 years
    Clearly, I just needed somebody else to share that this idea was valid. It works like a charm, and doesn't appear to be any slower to attach than the regular debugger.
  • Richard
    Richard almost 15 years
    You can do this with a single .exe and a command line option. If started as a console app, the startup thread calls Service.Start(), waits for a keypress (or something) then calls Service.Stop(). Thus allow almost all the code to be debugged.
  • dan-gph
    dan-gph about 14 years
    What is the 'Output type' in the project properties? 'Console Application'?
  • sgmoore
    sgmoore about 14 years
    Yes it is Console Application.
  • TomTom
    TomTom over 13 years
    +1 - basically the only way is NOT TO HAVE A SERVICE during development / debugging and un it from a cmd line application. A Service itself is a pain to debug.
  • Jay Imerman
    Jay Imerman over 9 years
    Um, maybe my head is thick? I added Debugger.Break() as the first line in OnStart(), and start the service. Now I get a progress bar saying it is starting. Then in VS I attach to process - it is listed but greyed out, I am unable to attach the debugger. Am I missing something?
  • Remi Guan
    Remi Guan about 8 years
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes.