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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1764187/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 06:55:15  来源:igfitidea点击:

Windows Services Recovery not restarting service

windowswindows-services

提问by M Schenkel

I configure the recovery for Windows services to restart with a one minute delay after failures. But I have never gotten it to actually restart the service (even with the most blatant errors).

我将 Windows 服务的恢复配置为在失败后延迟一分钟重新启动。但是我从来没有让它真正重新启动服务(即使有最明显的错误)。

I do get a message in the EventViewer:

我确实在 EventViewer 中收到一条消息:

The description for Event ID ( 1 ) in Source ( MyApp.exe ) cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer. You may be able to use the /AUXSOURCE= flag to retrieve this description; see Help and Support for details. The following information is part of the event: Access violation at address 00429874 in module 'MyApp.exe'. Write of address 00456704.

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

Is there something else I have to do? Is there something in my code (I use Delphi) which needs to be set to enable this?

还有什么我需要做的吗?我的代码(我使用 Delphi)中是否有需要设置以启用此功能的内容?

回答by ReinstateMonica Larry Osterman

Service Recovery is intended to handle the case where a service crashes - so if you go to taskmgr and right click "end process" on your service process, the recovery logic should kick in. I don't believe that the service recovery logic kicks in if your service exits gracefully (even if it exits with an error).

服务恢复旨在处理服务崩溃的情况 - 因此,如果您转到 taskmgr 并右键单击服务进程上的“结束进程”,则恢复逻辑应该会启动。我不相信服务恢复逻辑会启动如果您的服务正常退出(即使它退出时出现错误)。

Also the eventvwr message indicates that your application called the ReportEvent API specifying event ID 1. But you haven't registered your event messages with the event viewer so it can't convert event ID 1 into a meaningful text string.

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

回答by suprit chaudhary

Service Recovery only works for unexpected exit like (exit(-1)) call. For all the way we use to stop the service in usual way will not works for recovery. If you want to stop service and still wants recovery to work, call exit(-1)and you will see error message as "service stopped with unexpected error" , and then your service will restart as recovery setting is.

服务恢复仅适用于(exit(-1))调用等意外退出。因为我们用来以通常方式停止服务的所有方式都不适用于恢复。如果您想停止服务但仍希望恢复工作,请调用exit(-1),您将看到错误消息“服务因意外错误而停止”,然后您的服务将按照恢复设置重新启动。

回答by Len Holgate

The Service Control Manager will attempt to restart your service if you've set it up to be restarted by the SCM. This is detailed herein the documentation for the SERVICE_FAILURE_ACTIONSstructure.

如果您已将服务设置为由 SCM 重新启动,则服务控制管理器将尝试重新启动您的服务。这是详细这里为文档中SERVICE_FAILURE_ACTIONS的结构。

A service is considered failed when it terminates without reporting a status of SERVICE_STOPPED to the service controller.

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

This can be fine tuned by setting the SERVICE_FAILURE_ACTIONS_FLAGstructure's fFailureActionsOnNonCrashFailuresflag, see here). You can set this setting from the Services applet by checking the "Enable actions for stops with errors" checkbox on the recovery tab.

这可以通过设置SERVICE_FAILURE_ACTIONS_FLAG结构的fFailureActionsOnNonCrashFailures标志来微调,请参见此处)。您可以通过选中恢复选项卡上的“为出现错误的停止启用操作”复选框,从服务小程序中设置此设置。

If this member is TRUE and the service has configured failure actions, the failure actions are queued if the service process terminates without reporting a status of SERVICE_STOPPED or if it enters the SERVICE_STOPPED state but the dwWin32ExitCode member of the SERVICE_STATUS structure is not ERROR_SUCCESS (0). If this member is FALSE and the service has configured failure actions, the failure actions are queued only if the service terminates without reporting a status of SERVICE_STOPPED.

如果此成员为 TRUE 并且服务已配置失败操作,如果服务进程终止而未报告 SERVICE_STOPPED 状态,或者如果它进入 SERVICE_STOPPED 状态但 SERVICE_STATUS 结构的 dwWin32ExitCode 成员不是 ERROR_SUCCESS (0),则失败操作将排队. 如果此成员为 FALSE 并且服务已配置失败操作,则仅当服务终止而未报告 SERVICE_STOPPED 状态时,失败操作才会排队。

So, depending on how you have structured your service, how you have configured your failure actions AND what you do when you have your 'fatal error' it may be enough to call ExitProcess()or exit()and return a non zero value. However, it's probably safest to ensure that your service exits without the code that's dealing with the SCM telling the SCM that your service has reached the SERVICE_STOPPEDstate. This ensures that your failure actions ALWAYS happen...

因此,根据您构建服务的方式、配置失败操作的方式以及遇到“致命错误”时的操作,调用ExitProcess()exit()返回非零值可能就足够了。但是,最安全的做法可能是确保您的服务退出,而无需处理 SCM 的代码告诉 SCM 您的服务已达到该SERVICE_STOPPED状态。这可确保您的失败操作始终发生...

回答by Kostadin

If you 'kill' service from task manager - forgot for recovery logic. In background task manager 'kills' process by 'stop service'. and as yuo can guess - this is not service failure. This forced me to kill it really with Visual Studio. In task manager right click on service process. Select debug. In Visual studio select Debug-> Terminate All. And now you have simulated service fail. In this case recovery logic works fine.

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