【问题标题】:Strange Problem with a .NET Windows Service.NET Windows 服务的奇怪问题
【发布时间】:2010-07-27 17:54:07
【问题描述】:

我有两个使用 C# 编写的 Windows 服务,遵循相同的模式和方法。

这两项服务均针对 Windows 7 虚拟机进行了开发测试,并在 Windows Server 2008 虚拟机上进行了 QA 测试。这两个服务在这些测试环境下安装和卸载了很多次都没有问题,但是在生产环境(Windows Server 2008)中安装时,这两个服务之一拒绝启动。

为了安装服务,我们使用 InstallUtil.exe 以及附加到服务的 ServiceInstaller 和 ServiceProcessInstaller 组件。

从表面上看,失败的服务安装成功。 InstallUtil.exe 报告成功并且服务出现在服务管理单元中。您还可以在注册表中的 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Blah Blah 下找到该服务。但是,如果您尝试启动该服务,您会得到以下信息:

net start blah.blah.exe "服务名称无效。"

...或通过服务管理单元... “Windows 无法在本地计算机上启动“Blah Blah”服务。错误 1053:该服务未及时响应启动或控制请求。”

我在服务类失败服务的构造函数中添加了一些事件日志记录,但它似乎没有被调用。

由于这是一个生产盒子,盒子上没有 Visual Studio,远程调试是不可能的。

我有没有其他方法可以获取有关为什么失败的服务没有启动的调试信息?

还有其他明显的原因可以让我看到这类问题吗?

编辑:我还应该提到.. Windows 事件查看器中存在问题的唯一其他证据是来自服务控制管理器的系统日志中的两条消息:

“在等待 Blah Blah 服务连接时达到超时(30000 毫秒)。

“由于以下错误,Blah Blah 服务无法启动: 服务没有及时响应启动或控制请求。”

编辑:已解决 这个问题最终是一个配置错误和一个隐藏它的错误的组合。请参阅下面的answer 了解更多详情。

【问题讨论】:

  • 生产系统上是否安装了正确版本的 .NET?
  • @Matt 是的,这个 .NET 3.5 已经在生产环境中了。
  • 只是在黑暗中拍摄:检查 Main 方法,默认情况下在 Program.cs 文件中。您说您将日志记录添加到服务类的构造函数中,但它似乎没有被调用。我会在 Main 方法的开头添加日志记录,以检查它是否被调用。可能是那里添加了一些初始化代码,在生产环境中运行不正常。
  • 明白。不想在这里打败一匹死马,但我有一个基于 .NET 的 Windows 服务,它时不时地无法在目标系统上运行。在每种情况下,问题都是由于该系统上的 .NET Framework 未正确安装或缺少服务包所致。验证目标系统上的 .NET Framework 是否与测试系统上的 .NET Framework 匹配。如果您在测试系统上安装了 .NET 2.0/3.0/3.5 服务包,请确保它们在生产系统上。在一种情况下,重新安装 .NET Framework 为我们解决了问题。
  • 为了澄清/补充 Matt 所说的内容,.NET 3.5 和 .NET 3.5 SP1 之间存在相当大的差异。您的生产机器上可能有 3.5,但您的代码很可能需要 SP1。

标签: c# debugging windows-services


【解决方案1】:

危险答案:“无效的自定义配置与错误的全局异常处理程序相结合如何在 .NET Windows 服务中表现出来?”

想通了。

问题的根本原因是 app.config 中的自定义配置部分无效。我们使用自定义配置部分从 app.config 配置服务,并且 ConfigurationSection 派生类的程序集和命名空间最近发生了变化。

事实证明,我们的生产配置在错误的程序集中寻找自定义 ConfigurationSection 的定义,并且在未能实例化它时引发的异常被一个 bug 隐藏,在服务生命周期的早期捕获的异常会尝试记录到自定义日志而不是应用程序事件日志。 (由于自定义事件日志中不存在事件日志源,这会从全局异常处理程序中抛出另一个异常,并且服务将在构造函数中终止。)

第二个异常没有被记录到任何地方,我们只是通过代码检查才发现它。

解决方案是修复配置并将全局异常处理程序修改为仅尝试使用服务名称作为事件日志源写入应用程序事件日志。 (InstallUtil 将服务名称注册为应用程序日志上的事件日志源。)

感谢大家的帮助!抱歉,这个特定问题最终对我们的设置如此具体。

【讨论】:

  • 我想我在这里遇到了同样的问题。我会检查的。谢谢
【解决方案2】:

从您描述的错误消息中可能会出现

net start blah.blah.exe "服务名称无效。"

你在Visual Studio中添加的服务安装组件中给服务起的名字不是你想的那样。

我遇到过很多次开发人员在安装时错误命名服务的问题。

【讨论】:

    【解决方案3】:

    您在服务启动时要做什么?

    还要检查运行服务的帐户以及该帐户是否具有必要的权限。

    【讨论】:

      【解决方案4】:

      我在编写自己的服务时遇到过很多次这样的问题,所以我只列出一堆在各个方面解决了我的问题的东西,希望它们对你有所帮助:

      1. 我不得不重新启动 services.msc,因为我已经卸载了它仍然认为它有引用的服务。但是,当我启动它时,“服务无效”

      2. 如果您从控制台应用程序创建服务(以便对其进行调试)但忘记将其更改回服务,则它不会启动。

      3. 当我使用 InstallUtil.exe 时,有时它会尝试安装多个副本,因此我切换到仅使用安装项目。

      希望在某种程度上有所帮助。

      【讨论】:

        【解决方案5】:

        这是一个常见问题。您的 Start 事件中有什么代码?

        您应该只有在服务启动时激活计时器的代码。这允许 Start 事件快速完成并通知控制器。如果执行时间超过此时间,您将收到收到的错误。可能有一些原因(可能与数据相关)为什么它在生产中需要更长的时间。

        当计时器计时,执行您的代码并停止计时器。显然,也将所有内容都放在 try/catch 中并记录异常。

        【讨论】:

        • 感谢您的回复,但这个问题比这要复杂一些。执行实际上在服务的构造函数中死亡。请参阅我在 OP 上的最后几个 cmets。
        • 如果 !SourceExists(mySourceName) 可以试试吗?将 InitializeComponent 之后的所有内容都放在 try/catch 中?我不明白为什么它不应该启动。
        【解决方案6】:

        这个错误可能发生在

        • 您的服务依赖于另一个服务/应用程序
        • 或由于无效的 app.config 配置

        在实体框架由于缺少权限而无法连接到数据库服务器时遇到了同样的问题。 最好向您的应用程序添加全局级别的错误日志记录机制,以便轻松调试问题。在某些情况下,事件查看器可能不会显示确切的详细信息。

        【讨论】:

          猜你喜欢
          • 2020-07-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-03-12
          • 1970-01-01
          • 2011-09-05
          相关资源
          最近更新 更多