How to debug the .NET Windows Service OnStart method?

后端 未结 16 1287
离开以前
离开以前 2020-12-01 00:13

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 int

相关标签:
16条回答
  • 2020-12-01 00:23

    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.

    0 讨论(0)
  • 2020-12-01 00:23

    Before I go in the topic one advise. Always use log specially if you are server side developer. Because there are some certain condition which you might not be able to produce while debugging the code in visual studio.

    Coming back to topic, I use Envoirnment.UserInteractive flag this is really handy see 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 UserInteractive flag set so i would run it as console application, In addition to that even you can run product build by double clicking it and attaching debugger with it if you like to test it.

    0 讨论(0)
  • 2020-12-01 00:24

    Use following Code in Service OnStart Method:

    System.Diagnostics.Debugger.Launch();
    

    Choose Visual Studio option from Pop Up message. Remember to run Visual Studio as Administrator.

    Note: To use it in only Debug mode, #if DEBUG compiler directive can be used, as follows. This will prevent accidental or Debugging in Release mode on Production server.

    #if DEBUG
        System.Diagnostics.Debugger.Launch();
    #endif
    
    0 讨论(0)
  • 2020-12-01 00:25

    Once you have a service that is installed using installutil.exe, you can alter the Start Parameters to jump into the debugger if the service is started:

    enter image description here

    When you manually start the service with the parameter -debugWithVisualStudio (or simply -d), it will automatically detect the correct project, and fire up the interactive debugger in Visual Studio:

    enter image description here

    To support this functionality, change the service's OnStart() 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 throwing an error, switch on exceptions from the Visual Studio menu DEBUG .. Exceptions. When you continue debugging, it will break on the exact line that is throwing the exception.

    enter image description here

    0 讨论(0)
  • 2020-12-01 00:27

    I know this is late but this is how we handle debuging Windows services

    First create a class which will act as the service.

    Add the appropriate methods for starting, stopping, pausing, etc...

    Add a windows form to the service project.

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

    Open the 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 you run in DEBUG mode the windows form will launch. Just remember to build in Release mode when finished. Of course the conditional compile variable can be anything you like. You could even create seperate projects so the debug form is its own project.

    Hope this helps

    0 讨论(0)
  • 2020-12-01 00:27

    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

    0 讨论(0)
提交回复
热议问题