gpt4 book ai didi

windows - 如何让 Windows SCM 在失败时重新启动我的服务

转载 作者:可可西里 更新时间:2023-11-01 12:48:02 24 4
gpt4 key购买 nike

我有一些用 delphi 编写的 Windows 服务,它们通常运行良好,但有时我确实会抛出一个可以被认为是致命的异常。发生这种情况时,服务将停止。

我的问题是如何以 SCM 将自动尝试重新启动服务的方式退出服务。 (我已经在服务管理器中设置了服务的恢复选项)

MSDN

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

我已阅读此博文 Using the Automatic Recovery Features of Windows Services但我不确定如何在 Delphi 中实现它。

我已经尝试过以下方法

  • 将 TService 的 ErrCode 属性设置为非零值。
  • 将 ServiceStop 事件的停止参数设置为 false。
  • 在 servicestop 事件处理程序中引发异常。

EDIT 2013-08-06 添加代码示例

代码现已更新以显示工作示例

这是我使用的代码,

procedure TTestService.ServiceExecute(Sender: TService);
begin

while not (Terminated or FFatalError) do
begin
ServiceThread.ProcessRequests(False);
ReportStatus;
Sleep(100);
end;

if FFatalError then
Halt(1);

end;

FFatalError 是 TTestService 类上的私有(private) bool 字段,在启动时初始化为 false,仅当工作线程(在 TTestService.ServiceStart 事件中启动)以致命异常终止时才设置为 true。

这里是工作线程的 OnTerminate 事件处理程序。

procedure TTestService.ThdTerm(Sender: Tobject);
var
E : Exception;
Thread : TThread;
begin
Thread := TThread(Sender);

if (Thread.FatalException <> nil) then
begin
E := Exception(Thread.FatalException);
GetExcCallStack(E);

EventLog.LogError(Thread.ClassName + ': ID:'+ IntToStr(Thread.ThreadID) +
' Stopped Unexpectedly!, '+ NEWLINE + E.ClassName +': ' + E.Message);
FFatalError := True;
end;

end;

最佳答案

如果失败,SCM 将重新启动您的服务。但是 Delphi 服务的所有正常终止模式都不算作失败。如果您可以从未处理的主服务线程引发异常,那么这将被视为失败。

但是,我认为强制终止被视为失败的进程的最简单方法是调用 ExitProcess。您同样可以调用 Delphi RTL 函数 Halt,它最终会调用 ExitProcess。但是,由于您的进程可能处于错误状态,我倾向于直接进入 ExitProcess

正如已经评论过的那样,首先避免异常将是理想的解决方案。

关于windows - 如何让 Windows SCM 在失败时重新启动我的服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18076851/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com