How to debug .NET Windows Service OnStart method?

I have .NET code that only works when installed as a Windows service. A failure prevents the service from even starting. I can’t understand how I can enter the OnStart method.

How to debug Windows Service Applications gives an agonizing hint:

Joining the service process allows you to debug most, but not all, of the service code; for example, since the service is already running, you cannot debug the code in the OnStart method of the service in this way or the code in the Main method that is used to load the service. One way around this is to create a temporary second service in your service application, which exists only to aid in debugging. You can install both services and run this "dummy" service to download the maintenance process. After the temporary service has started this process, you can use the Debug menu in Visual Studio to join the service process.

However, I don’t understand how exactly you should create a dummy service to load the maintenance process.

+47
debugging c #
Jul 28 '09 at 20:27
source share
16 answers

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

System.Diagnostics.Debugger.Launch() 

This will offer you the debugger you want to use. Just install the solution already in Visual Studio and select this instance from the list.

+82
Jul 28 '09 at 20:30
source share

I usually add a method like this:

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

it will only be called to create your project's Debug projects, and it will pause execution and allow you to attach a debugger.

+8
Jul 28 '09 at 20:53
source share

After you have the service installed with installutil.exe , you can change the Start Parameters to go to the debugger if the service is running:

enter image description here

When you manually start the service with the -debugWithVisualStudio (or just -d ) -d , it automatically detects the correct project and launches the interactive debugger in Visual Studio:

enter image description here

To support this functionality, change the OnStart() service function:

 /// <summary> /// Executed when the service is started. /// </summary> /// <param name="args">Command line arguments.</param> protected override void OnStart(string[] args) { try { //How to debug when running a Windows Service: // 1. Right click on the service name in Windows Service Manager. // 2. Select "Properties". // 3. In "Start Parameters", enter "-d" (or "-debugWithVisualStudio"). // 4. Now, when you start the service, it will fire up Visual Studio 2012 and break on the line below. // 5. Make sure you have UAC (User Access Control) turned off, and have Administrator privileges. #if DEBUG if (((ICollection<string>)args).Contains("-d") || ((ICollection<string>)args).Contains("-debugWithVisualStudio")) { Debugger.Launch(); // Launches VS2012 debugger. } #endif ShellStart(args); base.OnStart(args); } catch (Exception ex) { // Log exception here. } } 

(optional) If you want to narrow down to the exact line of code where the service is causing the error, include exceptions from the Visual Studio DEBUG .. Exceptions menu. When you continue debugging, it will break on the exact line that throws an exception.

enter image description here

+6
Sep 24 '13 at 18:52
source share

Everything works perfectly!

 protected override void OnStart(string[] args) { System.Diagnostics.Debugger.Launch(); } 
+5
Feb 10 '11 at 18:42
source share

The options described above do not work in Windows 8.

I added Thread.Sleep (15000); into my OnStart () method and set a breakpoint on the next line of code. This gives me 15 seconds to attach the VS debugger to my process after starting the service and allowed me to debug the OnStart () method well.

+4
Mar 12 '13 at 13:29
source share

You can add a line of code as follows:

 System.Diagnostics.Debugger.Break() 

in which a window appears asking you to choose which debugger to use for debugging, for example. allowing you to connect to Visual Studio and enter code.

cm

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

+3
Jul 28 '09 at 20:31
source share

You can create a companion project for a Windows Service that runs as a console application but accesses the service methods using Reflection. See here for details and an example: http://ryan.kohn.ca/articles/how-to-debug-a-windows-service-in-csharp-using-reflection/ .

+1
Feb 10 '11 at 19:01
source share

I know it's late, but we also handle Windows service debugging

First create a class that will act as a service.

Add appropriate methods to start, stop, pause, etc.

Add a window form to a service project.

In the service code, create the service class created above and make the calls necessary to start and stop the service in the ServiceBase class

Open Program.cs and add the following

 #if DEBUG [STAThread] #endif static void Main() { try { #if DEBUG Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new DebugForm()); #else ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new YourWindowsService() }; ServiceBase.Run(ServicesToRun); #endif } catch (Exception e) { logger.Error(DateTime.Now.ToString() + " - " + e.Source + " - " + e.ToString() + "\r\n------------------------------------\r\n"); } } 

When launched in DEBUG mode, a window form will start. Just remember to build in Release mode when you're done. Of course, the compilation conditional variable can be anything you like. You can even create separate projects, so the debug form is your own project.

Hope this helps

+1
Apr 6 '13 at 1:08
source share

You can also try the System.Diagnostics.Debugger.Launch () method. This helps when displaying the debugger pointer at the specified location, and you can debug the code.

Before this step, install your service.exe using the command line command line of Visual Studio - installutil projectservice.exe

Then start the service from the control panel β†’ "Administration" β†’ "Computer Management" β†’ "Service and Application" β†’ "Services" β†’ "Name of your service"

+1
Aug 09 '13 at 10:10
source share

Use the following code in the OnStart method:

 System.Diagnostics.Debugger.Launch(); 

Select a Visual Studio option from the pop-up message. Remember to run Visual Studio as an administrator.

Note. To use it only in debug mode, you can use the #if DEBUG compiler directive, as shown below. This will prevent accidental or debugging in Release mode on the Production server.

 #if DEBUG System.Diagnostics.Debugger.Launch(); #endif 
+1
Dec 24 '14 at 9:28
source share

As others have pointed out, you need to add a debugger break to the OnStart-Method:

 #if DEBUG System.Diagnostics.Debugger.Break() #endif 

Also start VisualStudio as an administrator and enable the process to be automatically debugged by another user (as explained here ):

 reg add "HKCR\AppID\{E62A7A31-6025-408E-87F6-81AEB0DC9347}" /v AppIDFlags /t REG_DWORD /d 8 /f 

(I also explained this here: https://stackoverflow.com/a/165441/ )

+1
Mar 01 '16 at 5:36
source share

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

0
Jul 28 '09 at 20:31
source share

Usually I have a console application that claims to be an SCM, for example. calls "Start", "Stop", after which I can simply turn on F5 in my main encoding / debugging goals, and also use Debugger.Break for debugging when the service was installed and started via SCM.

This means that a little more work is needed to get started. I have a lib class that contains all the utility code, with a class that provides the ability to start and stop so that both Windows service classes and the console application can call.

Matt

0
Jul 29 '09 at 7:41
source share

If you add Debugger.Launch () to your OnStart method and this does not work, you may have the same problem as me, namely, the exception occurred in the constructor, so OnStart was never called. (headache)

(sorry if this was a comment on someone else's answer, but I do not have enough comments for comments)

0
Feb 28 '14 at 23:51
source share

Before you go into the topic, I advise. Always use the log specifically if you are a server-side developer. Because there are some certain conditions that you cannot make when debugging code in visual studio.

Returning to the topic, I use the Envoirnment.UserInteractive checkbox, it is really convenient to see it in my code below

 public static void Main(string[] args) { if (System.Environment.UserInteractive) { string parameter = string.Concat(args); switch (parameter) { case "--install": ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location }); break; case "--uninstall": ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location }); break; default: WindowsService service = new WindowsService(); service.OnStart(args); Console.ReadKey(); service.OnStop(); break; } } else { ServiceBase.Run(new WindowsService()); } } 

From visual studio you will get the UserInteractive flag so that I run it as a console application. In addition, you can start assembling the product by double-clicking it and attaching a debugger to it if you want to check it.

0
Mar 10 '14 at 23:28
source share

I have an interesting way to do this. I am adding another configuration called DebugNoService

  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugNoService|AnyCPU' "> <OutputPath>.\</OutputPath> <AllowUnsafeBlocks>false</AllowUnsafeBlocks> <BaseAddress>285212672</BaseAddress> <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow> <ConfigurationOverrideFile> </ConfigurationOverrideFile> <DefineConstants>DEBUG;TRACE;DEBUGNOSERVICE</DefineConstants> <DocumentationFile> </DocumentationFile> <DebugSymbols>true</DebugSymbols> <FileAlignment>4096</FileAlignment> <NoStdLib>false</NoStdLib> <NoWarn> </NoWarn> <Optimize>false</Optimize> <RegisterForComInterop>false</RegisterForComInterop> <RemoveIntegerChecks>false</RemoveIntegerChecks> <TreatWarningsAsErrors>false</TreatWarningsAsErrors> <WarningLevel>4</WarningLevel> <DebugType>full</DebugType> <ErrorReport>prompt</ErrorReport> <UseVSHostingProcess>false</UseVSHostingProcess> </PropertyGroup> 

I use the #if directive. ProjectInstaller.cs

 #if !DEBUGNOSERVICE static void Main() { System.ServiceProcess.ServiceBase[] ServicesToRun; ..... } #endif 

I add a window shape and I also wrap the window shape in

 #if DEBUGNOSERVICE ... static void Main() { Form form; Application.EnableVisualStyles(); Application.DoEvents(); form = new <the name of the form>(); Application.Run(form); } ... #endif 

depending on the selected configuration, the code runs as a Windows form application, which can be easily debugged or as a service.

If it seems to you that a lot of work, but it always worked and very easily debugs the code. You can add all kinds of output to the form so that you can watch their launch.

0
Mar 01 '16 at 6:11
source share



All Articles