如何在Visual Studio中调试Windows服务?

Paw*_*anS 81 c# windows-services visual-studio-2010 visual-studio

是否可以在Visual Studio中调试Windows服务?

我用的代码就像

System.Diagnostics.Debugger.Break();
Run Code Online (Sandbox Code Playgroud)

但它给出了一些代码错误,如:

我收到两个事件错误:eventID 4096 VsJITDebugger和"服务没有及时响应启动或控制请求."

Chi*_*rag 117

在服务OnStart方法中使用以下代码:

System.Diagnostics.Debugger.Launch();
Run Code Online (Sandbox Code Playgroud)

从弹出消息中选择Visual Studio选项.

注意:要仅在调试模式下使用它,#if DEBUG可以使用编译器指令,如下所示.这将防止生产服务器上的发布模式中的意外或调试.

#if DEBUG
    System.Diagnostics.Debugger.Launch();
#endif
Run Code Online (Sandbox Code Playgroud)

  • 记得以管理员身份运行VS. 然后它将在列表中可用. (6认同)

Paw*_*anS 60

你也可以试试这个.

  1. 创建Windows服务并安装并启动.... 也就是说,Windows服务必须在您的系统中运行.
  2. 当您的服务正在运行时,请转到" 调试"菜单,单击" 附加进程"(或在旧的Visual Studio中处理)
  3. 找到你正在运行的服务,并确保将显示所有用户进程,并在所有会话显示过程中选择,如果不然后选择它.

在此输入图像描述

  1. 单击" 附加"按钮
  2. 单击确定
  3. 单击关闭
  4. 设置一个断点到您想要的位置并等待执行.只要代码到达那一点,它就会自动调试.
  5. 请记住,将断点放在可到达的位置,如果它是onStart(),则停止并再次启动该服务

(经过大量的谷歌搜索后,我在"如何在Visual Studio中调试Windows服务"中找到了这个.)

  • 在VS2013 Update 5中看不到此选项.:( (2认同)

ang*_*son 21

您应该将所有将从服务项目中执行操作的代码分离到单独的项目中,然后创建一个可以正常运行和调试的测试应用程序.

服务项目只是实现服务部分所需的shell.

  • 我不知道它会如何"加倍"工作.当然,它会增加一些额外的项目开销,并将服务中的代码分离到第三个项目,但除此之外,你不会复制代码,你会移动它,并参考该项目. (8认同)
  • 当然是可以的,但是如果在开发的时候把服务部分去掉,开发windows服务就容易多了。 (2认同)
  • ^ + 1。它使管理服务的工作加倍,就开发时间而言,服务几乎为零,而您只需执行一次。调试序列是痛苦的-而是使其作为命令行双重启动。检查谷歌的预定义包装类允许这样做(他们使用反射来模拟开始/停止没有服务类)。一小时的工作,大量的节省,净损失:负数-您可以节省时间。 (2认同)

Pau*_*erø 14

要么就像Lasse V. Karlsen所建议的那样,要么在服务中设置一个等待调试器附加的循环.最简单的是

while (!Debugger.IsAttached)
{
    Thread.Sleep(1000);
}

... continue with code
Run Code Online (Sandbox Code Playgroud)

这样你可以启动服务,在Visual Studio中你选择"附加到进程......"并附加到你的服务,然后恢复正常的服务.

  • 我们也使用了这样的代码`if(Environment.UserInteractive){InteractiveRun(args); } else {Service instance = new Service(); ServiceBase [] servicesToRun = new ServiceBase [] {instance}; ServiceBase.Run(servicesToRun); }` (3认同)

ta.*_*.is 7

鉴于ServiceBase.OnStart具有protected可见性,我沿着反射路线进行调试.

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);
}
Run Code Online (Sandbox Code Playgroud)

请注意,Thread默认情况下是前台线程.return从荷兰国际集团Main,而人造服务线程运行不会终止进程.