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


当前回答

对于现有Windows服务程序的故障排除,请像其他人建议的那样使用'Debugger.Break()'。

对于新的Windows服务程序,我建议使用James Michael Hare的方法http://geekswithblogs.net/BlackRabbitCoder/archive/2011/03/01/c-toolbox-debug-able-self-installable-windows-service-template-redux.aspx

其他回答

为了调试Windows服务,我结合了GFlags和一个由regedit创建的.reg文件。

运行GFlags,指定ex -name和vsjitdebugger 运行regedit并转到GFlags设置选项的位置 从文件菜单中选择“导出密钥” 将该文件保存在扩展名为.reg的某处 任何时候你想调试服务:双击.reg文件 如果要停止调试,请双击第二个.reg文件

或者保存以下代码片段并用所需的可执行名称替换servicename.exe。


debugon.reg:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\servicename.exe]
"GlobalFlag"="0x00000000"
"Debugger"="vsjitdebugger.exe"

debugoff.reg:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\servicename.exe]
"GlobalFlag"="0x00000000"

我通常做的是将服务的逻辑封装在一个单独的类中,并从一个“runner”类开始。这个运行器类可以是实际的服务,也可以只是一个控制台应用程序。所以你的解决方案至少有3个项目:

/ConsoleRunner
   /....
/ServiceRunner
   /....
/ApplicationLogic
   /....

只是粘贴

Debugger.Break();

代码中的任何地方。

例如,

internal static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    private static void Main()
    {
        Debugger.Break();
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[]
        {
            new Service1()
        };
        ServiceBase.Run(ServicesToRun);
    }
}

它会点击Debugger.Break();当你运行程序时。

在开发和调试Windows服务时,我通常通过添加/console启动参数并检查来将其作为控制台应用程序运行。让生活更轻松。

static void Main(string[] args) {
    if (Console.In != StreamReader.Null) {
        if (args.Length > 0 && args[0] == "/console") {
            // Start your service work.
        }
    }
}

最好的选择是使用“系统”。诊断的名称空间。

将代码包含在if else块中,用于调试模式和发布模式,如下所示,在visual studio中切换调试和发布模式。

#if DEBUG  // for debug mode
       **Debugger.Launch();**  //debugger will hit here
       foreach (var job in JobFactory.GetJobs())
            {
                //do something 
            }

#else    // for release mode
      **Debugger.Launch();**  //debugger will hit here
     // write code here to do something in Release mode.

#endif