Is it possible to debug the Windows services in Visual Studio?
I used code like
System.Diagnostics.Debugger.Break();
but it is givi
Either that as suggested by Lasse V. Karlsen, or set up a loop in your service that will wait for a debugger to attach. The simplest is
while (!Debugger.IsAttached)
{
Thread.Sleep(1000);
}
... continue with code
That way you can start the service and inside Visual Studio you choose "Attach to Process..." and attach to your service which then will resume normal exution.
I just added this code to my service class so I could indirectly call OnStart, similar for OnStop.
public void MyOnStart(string[] args)
{
OnStart(args);
}
Unfortunately, if you're trying to debug something at the very start of a Windows Service operation, "attaching" to the running process won't work. I tried using Debugger.Break() within the OnStart procecdure, but with a 64-bit, Visual Studio 2010 compiled application, the break command just throws an error like this:
System error 1067 has occurred.
At that point, you need to set up an "Image File Execution" option in your registry for your executable. It takes five minutes to set up, and it works very well. Here's a Microsoft article where the details are:
How to: Launch the Debugger Automatically
You can also try this.
(After a lot of googling, I found this in "How to debug the Windows Services in Visual Studio".)
You should separate out all the code that will do stuff from the service project into a separate project, and then make a test application that you can run and debug normally.
The service project would be just the shell needed to implement the service part of it.
Given that ServiceBase.OnStart
has protected
visibility, I went down the reflection route to achieve the debugging.
private static void Main(string[] args)
{
var serviceBases = new ServiceBase[] {new Service() /* ... */ };
#if DEBUG
if (Environment.UserInteractive)
{
const BindingFlags bindingFlags =
BindingFlags.Instance | BindingFlags.NonPublic;
foreach (var serviceBase in serviceBases)
{
var serviceType = serviceBase.GetType();
var methodInfo = serviceType.GetMethod("OnStart", bindingFlags);
new Thread(service => methodInfo.Invoke(service, new object[] {args})).Start(serviceBase);
}
return;
}
#endif
ServiceBase.Run(serviceBases);
}
Note that Thread
is, by default, a foreground thread. return
ing from Main
while the faux-service threads are running won't terminate the process.