tags:

views:

1569

answers:

5

I have code written in .net that only fails when installed as a windows service. The failure doesn't allow the service to even start. I can't figure out how I can step into the OnStart method.

http://msdn.microsoft.com/en-us/library/7a50syb3%28VS.80%29.aspx gives a tantalizing clue:

Attaching to the service's process allows you to debug most but not all of the service's code; for example, because the service has already been started, you cannot debug the code in the service's OnStart method this way, or the code in the Main method that is used to load the service. One way to work around this is to create a temporary second service in your service application that exists only to aid in debugging. You can install both services, and then start this "dummy" service to load the service process. Once the temporary service has started the process, you can then use the Debug menu in Visual Studio to attach to the service process.

However, I'm not clear how it is exactly that you are supposed to create the dummy service to load the service process.

+5  A: 

One thing you could do as a temporary workaround is to launch the debugger as the first line of code in the OnStart

System.Diagnostics.Debugger.Launch()

This will prompt you for the debugger you'd like to use. Simply have the solution already open in Visual Studio and choose that instance from the list.

palehorse
This is not working for me. The error I get is Unhandled exception at 0x7c812aeb in xxxxService.exe: 0xC06D007E: Module not found, and the breakpoints are never reached. This is however, quite different then the error I am getting without the debugger.Launch code included.
Nathan
Do you have Visual Studio installed on the machine where the service is running?
palehorse
Yes, I have both Visual Studio 2005 Professional, and Visual Studio 2008 professional installed on the machine.
Nathan
Hmm....are the binaries that are running compiled in debug mode? I've never seen that not work before.
palehorse
The build script does appear to be setting the configuration to debug mode. Is there any way to directly check the built assemblies?
Nathan
Is it producing .dbd files? Are they located in the same folder as the .dll's?
palehorse
Also, if I click "break" when the exception window comes up, I get "No symbols are loaded for any call stack frame. The source code cannot be displayed."
Nathan
I am not seeing any .dbd files. I am also not familiar with .dbd files within the .net framework. Did you perhaps mean .pdb files? The .pdb files are in the root ouput of the build script, but I will need to check if they are getting copied by installutil - which I am a little bit new to.
Nathan
Yes, I did mean .pdb files, sorry about that. InstallUtil should not be copying files anywhere, rather it simply does the necessary registrations to let Windows know about the service.It's possible that the exceptions are happening before your OnStart code, for example in the constructor or in the service controller class that creates the instance of your service. You could try putting the Debugger.Launch() statements in one of those places.
palehorse
I put the Debugger.Launch in the main method, and now I am able to step into the code. Thanks!
Nathan
+1  A: 

You can add a line of code like this:

System.Diagnostics.Debugger.Break()

which will bring up a window prompting you to choose which debugger to use to debug, e.g. allowing you to attach with Visual Studio and step into the code.

see:

http://msdn.microsoft.com/en-us/library/system.diagnostics.debugger.break.aspx

Alex Black
A: 

Try adding Debugger.Break inside the problematic method. When the service will start an exception will be thrown and widows should offer to debug it using visual studio.

Dror Helper
+1  A: 

I tend to add a method like this:

    [Conditional("DEBUG")]
    private void AttachDebugger()
    {
        Debugger.Break();
    }

it will only get called on Debug builds of you project and it will pause execution and allow you to attach the debugger.

SpaceghostAli
A: 

I usually have a console app that pretends to be the SCM e.g. calls Start, Stop which I can then just F5 into for my main coding/debugging purposes, and use the Debugger.Break for debugging when the service has been installed and started via the SCM.

It means a bit more work to start with, I have a class lib that contains all the service code, with a class that exposes Start and Stop that the Windows Service class and the console app can both call.

Matt

Matt