我有一些我用 delphi 编写的 Windows 服务,它们通常工作得很好,但是有时我确实会抛出一个可以被认为是致命的异常。当这种情况发生时,服务被设计为停止。
我的问题是如何以 SCM 将自动尝试重新启动服务的方式退出服务。(我已经在服务管理器中设置了服务的恢复选项)
MSDN状态
当服务终止而没有向服务控制器报告 SERVICE_STOPPED 状态时,服务被视为失败。
我已经阅读了这篇博客文章使用 Windows 服务的自动恢复功能,但我不确定如何在 delphi 中实现这一点。
我已经尝试过以下
- 将 TService 的 ErrCode 属性设置为非零值。
- 将 ServiceStop 事件的已停止参数设置为 false。
- 在 servicestop 事件处理程序中引发异常。
编辑 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 类上的私有布尔字段,在启动时初始化为 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;