Windows服务恢复未重新启动服务

23

我将Windows服务的恢复设置为在失败后延迟一分钟重新启动。但是我从未成功地将其重新启动(即使出现最明显的错误)。

我在EventViewer中收到一条消息:

源(MyApp.exe)中事件ID(1)的描述找不到。本地计算机可能没有必要的注册表信息或消息DLL文件以显示来自远程计算机的消息。您可以使用/AUXSOURCE=标志检索此说明; 有关详细信息,请参见帮助和支持。以下信息是事件的一部分:模块“MyApp.exe”中地址00429874处的访问冲突。对地址00456704的写入。

我需要做其他事情吗?是否需要在我的代码(我使用Delphi)中设置以启用此功能?


这个问题可能会有所帮助 https://dev59.com/-XVC5IYBdhLWcg3wqzDV?rq=1 - tom redfern
4个回答

25

服务恢复旨在处理服务崩溃的情况 - 因此,如果您打开任务管理器并右键单击服务进程上的“结束进程”,则恢复逻辑应该启动。我认为,即使服务以错误退出,服务恢复逻辑也不会启动。

另外,事件查看器消息表明,您的应用程序调用了ReportEvent API,并指定了事件ID 1。但是,您尚未向事件查看器注册事件消息,因此它无法将事件ID 1转换为有意义的文本字符串。


2
谢谢。这让情况变得清晰了。我发现当我从任务管理器中执行“结束进程”时,它会在事件查看器中产生以下内容: 将在60000毫秒内执行以下纠正措施:重新启动服务。现在我的问题(与我的编码相关)是要使其以“非优雅”的方式终止,以便恢复逻辑会启动。 - M Schenkel
1
如果您调用ExitProcess,那应该就足够了。 - Larry Osterman

13

仅当出现意外退出,例如 (exit(-1)) 调用时,Service Recovery 才起作用。 对于通常用于停止服务的所有方式,都无法进行恢复。 如果您想停止服务但仍希望恢复功能正常工作,请调用 exit(-1),您将看到错误消息 "service stopped with unexpected error",然后您的服务将按照恢复设置重新启动。


4
若您正在寻找确切的方法,请尝试使用 Environment.Exit(-1);。该方法会结束程序执行,参数 -1 表示程序以异常的方式退出。 - Chris Haines

4
服务控制管理器将尝试重新启动您的服务,如果您已经设置它通过 SCM 重新启动。在 SERVICE_FAILURE_ACTIONS 结构的文档 这里 中有详细说明。

当服务终止且未向服务控制器报告 SERVICE_STOPPED 状态时,该服务被视为失败。

可以通过设置 SERVICE_FAILURE_ACTIONS_FLAG 结构的 fFailureActionsOnNonCrashFailures 标志来微调此设置,详见 这里。您可以通过在恢复选项卡上选中“启用停止错误操作”复选框来从服务应用程序设置此设置。
如果此成员为TRUE并且服务已配置失败操作,则在服务进程终止而没有报告SERVICE_STOPPED状态或者进入SERVICE_STOPPED状态但是SERVICE_STATUS结构体的dwWin32ExitCode成员不等于ERROR_SUCCESS(0)时,将排队执行失败操作。如果此成员为FALSE并且服务已配置失败操作,则仅在服务终止而没有报告SERVICE_STOPPED状态时,才会排队执行失败操作。
因此,根据您构建服务的方式、配置失败操作的方式以及在出现“致命错误”时所做的操作,仅调用ExitProcess()或exit()并返回非零值可能足够。然而,最安全的做法可能是确保您的服务退出时不包含处理SCM的代码,这样可以告诉SCM您的服务已达到SERVICE_STOPPED状态。这确保了始终执行失败操作...

2

如果您从任务管理器中“终止”服务 - 忘记了恢复逻辑。 在后台任务管理器中,“停止服务”会“终止”进程。 你可以猜到 - 这不是服务故障。 这迫使我真正用Visual Studio杀死它。 在任务管理器中右键单击服务进程。 选择调试。 在Visual Studio中选择Debug->Terminate All。 现在,您已经模拟了服务失败。 在这种情况下,恢复逻辑运作良好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接