已签名的程序集阻止我的服务启动
在运行 Windows 2003 Server 的计算机上,当我使用 Verisign signtool.exe 对服务中的程序集进行签名时,该程序在计算机启动时无法启动。 事件日志有两个事件:
“等待 xxx Service 服务连接超时(30000 毫秒)”。 和 “由于以下错误,xxx Service 服务无法启动: 该服务没有及时响应启动或控制请求。”
机器运行后,它启动正常。在 XP 和 Vista 中启动正常。当程序集未签名时,它启动正常。
When I sign the assemblies in my service with the Verisign signtool.exe, it fails to start when the machine starts, on a machine running Windows 2003 Server. The event log has two events:
"Timeout (30000 milliseconds) waiting for the xxx Service service to connect."
and
"The xxx Service service failed to start due to the following error:
The service did not respond to the start or control request in a timely fashion."
It starts fine once the machine is running. It starts fine in XP and Vista. It starts fine when the assemblies are unsigned.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
对于已签名的 .NET 服务可执行文件来说,此问题非常常见:该服务将无法在启动时启动,但在随后手动启动时运行良好。 是否使用 ServiceBase.RequestAdditionalTime 无关紧要:事实上,在服务启动请求超时之前根本不会执行任何用户代码。 这种影响在没有互联网连接的机器上更为明显:在这种情况下,即使从 SCM 手动启动服务也会失败。
要解决此问题,请在加载时禁用 Authenticode 签名验证,以便创建发布者证据,通过将以下元素添加到您的 .exe.config 文件中:
发布者证据是一项很少使用的代码访问安全 (CAS) 功能:只有当您的服务依赖于 PublisherMembershipCondition 时,禁用它才会导致问题。 在所有其他情况下,它将不再需要运行时执行昂贵的证书检查(包括吊销列表查找),从而消除永久性或间歇性启动失败。
编辑,2010 年 7 月:对于使用 .NET Framework 4.0 版的应用程序,不再需要此解决方法。
This problem is very common for signed .NET service executables: the service will fail to start at boot time, but run fine when started manually afterwards. Whether ServiceBase.RequestAdditionalTime is used is irrelevant: in fact, no user code is executed at all prior to the service start request timing out. This effect is even more pronounced on machines without Internet connectivity: in that case, even manually starting the service from the SCM will fail.
To resolve this issue, disable the verification of the Authenticode signature at load time in order to create Publisher evidence, by adding the following elements to your .exe.config file:
Publisher evidence is a little-used Code Access Security (CAS) feature: only if your service relies on the PublisherMembershipCondition will disabling it cause issues. In all other cases, it will make the permanent or intermittent startup failures go away, by no longer requiring the runtime to do expensive certificate checks (including revocation list lookups).
Edit, July 2010: For applications using version 4.0 of the .NET Framework, this workaround is no longer required.
对程序集进行 Authenticode 签名可能会对冷启动产生非常负面的影响。 有关详细信息,请参阅此知识库文章。
http://support.microsoft.com/default.aspx/kb/936707
Authenticode signing your assemblies can have a very negative effect on cold startup. See this KB article for details.
http://support.microsoft.com/default.aspx/kb/936707
正如 spacedog 所说,Authenticode 会对启动时间产生不良影响。 那么问题是你要签什么? 仅对服务可执行文件进行 Authenticode 签名就足够了,而服务可执行文件必须仅引用强命名程序集。 因此验证 Authenticode 签名的开销。
您可以将程序集安装到 GAC - 如果可能 - 这将稍微提高启动性能,因为会跳过强名称验证(请参阅 Authenticode 和程序集)和/或者如果启动时间仍然是一个问题,您也可以 ngen 程序集。
来自 Romulo A. Ceccon 对Windows 服务启动超时的回答:
除了
SetServiceStatus
之外,您还可以尝试通过调用ServiceBase.RequestAdditionalTime
。As spacedog said, Authenticode can have a bad impact on startup time. So the question is what are you signing? It should be sufficient to Authenticode sign only your service executable which in turn must only reference strong named assemblies. Thus the overhead of verifying the Authenticode signature.
You could install your assemblies to the GAC - if possible - this will slightly boost startup performance because the strong name validation is skipped (see Authenticode and Assemblies) and / or you could also ngen your assemblies if startup time still is an issue.
From the answer to Windows service startup timeout by Romulo A. Ceccon:
In addition to
SetServiceStatus
you could also try to tell the Service Control Manager (SCM) that the service needs additional time to start up by callingServiceBase.RequestAdditionalTime
.