- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有一些用 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 中实现它。
我已经尝试过以下方法
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/
我是一名优秀的程序员,十分优秀!