如何调试 Windows 服务?

新手上路,请多包涵

我阅读了有关该主题的 MSDN 文章。去引用:

因为服务必须在服务控制管理器的上下文中而不是在 Visual Studio 中运行,所以调试服务不像调试其他 Visual Studio 应用程序类型那样简单。要调试服务,您必须启动服务,然后将调试器附加到正在运行它的进程。然后,您可以使用 Visual Studio 的所有标准调试功能来调试您的应用程序。

现在我的问题是我的服务一开始就无法启动。首先它崩溃了,然后说:

MyServiceName.exe [3596] 中发生未处理的异常 (System.Runtime.InteropServices.COMException)

并建议我调试它(当我选择一个时,调试器实例会立即崩溃)。然后它说

无法在本地计算机上启动 MyServiceName 服务。错误 1053:服务没有及时响应启动或控制请求

那么,如何调查/调试我的服务无法启动的原因?问题是我创建了一个控制台应用程序,该应用程序完全符合服务的功能并且工作正常。 (我的意思是我刚刚将 OnStart () 方法和主循环的内容复制到 main)。

任何帮助,将不胜感激。

该服务是用 C# 编写的,大量使用互操作。我正在使用 VS2008

原文由 Armen Tsirunyan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

您可以使用参数让您的应用程序决定是作为服务启动还是作为常规应用启动(即在这种情况下显示表单或启动服务):

 static void Main(string[] args)
{
    if ((1 == args.Length) && ("-runAsApp" == args[0]))
    {
        Application.Run(new application_form());
    }
    else
    {
        System.ServiceProcess.ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] { new MyService() };
        System.ServiceProcess.ServiceBase.Run(ServicesToRun);
    }
}

现在,如果您传递参数“-runAsApp”,您可以正常调试应用程序 - SCM 不会传递此参数,因此您也可以将其用作服务而无需任何代码更改(前提是您源自 ServiceBase )

编辑:

与 Windows 服务的另一个区别是身份(这对于 InterOp 可能尤其重要)——您要确保在“应用程序”模式和服务模式下以相同的身份进行测试。

为此,您可以在应用程序模式下使用模拟(如果有帮助,我可以发布一个 C# 包装器,但这可以很容易地用 Google 搜索)来使用您的 Windows 服务将在其下运行的相同身份,即通常是 LocalService 或 NetworkService。

如果需要其他身份,您可以将设置添加到 app.config 以允许您决定是否使用凭据,如果是,则模拟哪个用户 - 这些设置在作为应用程序运行时将处于活动状态,但对于 Windows 服务关闭(因为该服务已经在所需的身份下运行):

   <appSettings>
    <add key="useCredentials" value="false"/>
    <add key="user" value="Foo"/>
    <add key="password" value="Bar"/>
  </appSettings>

原文由 BrokenGlass 发布,翻译遵循 CC BY-SA 2.5 许可协议

在您的 OnStart 中添加大量详细的日志记录。这是痛苦的老派,但它有效。

原文由 RQDQ 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏