是否有比通过Windows服务控制管理器启动服务,然后将调试器附加到线程更简单的方法来逐步遍历代码?这有点麻烦,我想知道是否有更直接的方法。


当前回答

只需将调试器放置在任何地方,并在启动时附加Visualstudio即可

#if DEBUG
    Debugger.Launch();
#endif

此外,你需要以管理员身份启动VS,并且你需要允许,一个进程可以由不同的用户自动调试(如下所述):

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

其他回答

您也可以通过命令提示符(sc.exe)启动服务。

就我个人而言,我会在调试阶段将代码作为独立程序运行,当大多数错误被解决后,再改为作为服务运行。

我过去所做的是有一个命令行开关,它可以作为服务或常规应用程序启动程序。然后,在我的IDE中,我将设置开关,以便我可以分步执行我的代码。

对于某些语言,您实际上可以检测它是否运行在IDE中,并自动执行此切换。

你在用什么语言?


static void Main()
{
#if DEBUG
                // Run as interactive exe in debug mode to allow easy
                // debugging.

                var service = new MyService();
                service.OnStart(null);

                // Sleep the main thread indefinitely while the service code
                // runs in .OnStart

                Thread.Sleep(Timeout.Infinite);
#else
                // Run normally as service in release mode.

                ServiceBase[] ServicesToRun;
                ServicesToRun = new ServiceBase[]{ new MyService() };
                ServiceBase.Run(ServicesToRun);
#endif
}

我喜欢能够调试我的服务的每个方面,包括在OnStart()中的任何初始化,同时仍然在SCM框架内执行完整的服务行为…没有“控制台”或“应用程序”模式。

为此,我在同一个项目中创建了第二个用于调试的服务。调试服务在正常启动时(即在服务MMC插件中),创建服务主机进程。这为您提供了一个可以附加调试器的进程,即使您还没有启动真正的服务。在将调试器附加到进程之后,启动真正的服务,您可以在服务生命周期中的任何位置进入它,包括OnStart()。

因为调试服务只需要极少的代码侵入,所以可以很容易地将其包含在服务设置项目中,并且通过注释掉一行代码和删除单个项目安装程序就可以很容易地从产品版本中删除调试服务。

细节:

1)假设你正在实现MyService,也创建MyServiceDebug。将两者添加到Program.cs中的ServiceBase数组中,如下所示:

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    static void Main()
    {
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] 
        { 
            new MyService(),
            new MyServiceDebug()
        };
        ServiceBase.Run(ServicesToRun);
    }

2)将真实服务和调试服务添加到服务项目的项目安装程序中:

在将服务项目输出添加到服务的设置项目时,将包括两个服务(真实的和调试的)。安装后,这两个服务都将出现在服务中。MMC插件。

3)启动MMC中的调试服务。

4)在Visual Studio中,将调试器附加到调试服务启动的进程。

5)启动真正的服务,享受调试。

static class Program
{
    static void Main()
    {
        #if DEBUG

        // TODO: Add code to start application here

        //    //If the mode is in debugging
        //    //create a new service instance
        Service1 myService = new Service1();

        //    //call the start method - this will start the Timer.
        myService.Start();

        //    //Set the Thread to sleep
        Thread.Sleep(300000);

        //    //Call the Stop method-this will stop the Timer.
        myService.Stop();

         #else
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] 
        { 
            new Service1() 
        };

        ServiceBase.Run(ServicesToRun);
         #endif
    }
}