我有一些我用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事件处理程序中引发异常.

编辑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;
如果SCM失败,SCM将重新启动您的服务.但是,Delphi服务中的所有正常终止模式都不算失败.如果您可以从未处理的主服务线程引发异常,那么这将被视为失败.

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

正如已经评论过的那样,首先避免例外将是理想的解决方案.

如何让Windows SCM在失败时重启我的服务的更多相关文章

  1. 如何让Windows SCM在失败时重启我的服务

    我有一些我用delphi编写的Windows服务,它们通常工作得很好,但有时我会得到一个可以被视为致命的异常抛出.发生这种情况时,该服务旨在停止.我的问题是如何以这样的方式退出服务,即SCM将自动尝试重新启动服务.(我已经在服务管理器中设置了服务的恢复选项)MSDN州AserviceisconsideredFailedwhenitterminateswithoutreportingastatuso

  2. 如何在同一域中的不同服务器上设置Windows服务之间的依赖关系

    我有一种情况,在不同服务器上的Windows服务启动之前,不应启动一台服务器上的Windows服务.我想要做的是设置服务依赖性,但标准的“scdepend=service2”似乎不适合这一点.我可以将服务代码包装在TryUntilSuccesful()类型的调用中,但我想知道是否有一种建议的方法来为同一域中的服务器之间的Windows服务设置依赖关系.同一台计算机上的Windo

  3. Centos7.2安装CDH5.7.2core steps

    软件准备jdk-8u121-linux-x64.rpmcloudera-manager-centos7-cm5.7.2_x86_64.tar.gzCDH-5.7.2-1.cdh5.7.2.p0.18-el7.parcelCDH-5.7.2-1.cdh5.7.2.p0.18-el7.parcel.sha更改为sha后缀manifest.jsonMysqL57-community-release-el

  4. Windows服务器中服务的起始顺序是什么

    我有一个Windows服务,在大多数服务器上工作正常.但是在一台服务器中,我看到它是在网络服务启动之前启动的.这导致服务挂起,因此操作系统无法启动.它也卡住了.什么是通常的服务启动顺序?我的Windows服务确实建立了TCP连接.我应该加一个延迟开始吗?

  5. CDH 5.9 CentOS 6.5 离线安装部署

    CDH5.9离线安装部署手册站在巨人的肩膀上面继续前进,不断的踩坑与填坑,感谢破击手的参考指南。ntp与自身进行同步需要一小段时间,大约需要5分钟。使用命令ntpstat检查服务启动后自身是否同步完成,如出现以下信息则完成。我试安装时,这点遗漏了,导致安装CDH的时候一直刷不出5.9版本,通过日志发现,没有manifest.json就会去下载,不能访问外网就报错了,但不影响安装CDH,还是mv一下吧。

  6. CDH在Centos 7离线安装

    不过最近要求在Centos7上离线安装,有点坑,网上的很多都是抄来抄去,安装到一半可能就走不下去,这里是本人亲测,遇到的问题都一一说明并且解决掉。Centos7自带java,我们查看一下版本:Cloudera官方给出:所以我们需要卸载本机自带的openJDK,安装我们自己的JDK到/usr/java/目录下。

  7. 权限 – 是否可以使用组策略授予管理Windows服务的权限?

    我真的很想知道这是否可能,如果是这样,你建议我在哪里寻找更多信息?

  8. centos7.2下搭建CDH5.8.3

    也就是主节点上面。--scm-hosthadoop1:CMS的主机,一般是和MysqL安装的主机是在同一个主机上。最后三个参数是:数据库名,数据库用户名,数据库密码。

  9. Windows下配置Git服务器和客户端 scm-manager

    配置scm-manager在机器上安装java环境,从http://java.com/zh_CN/download/manual.jsp选择脱机版下载安装从https://bitbucket.org/sdorra/scm-manager/wiki/download下载最新的scm-server-1.24-app.zip安装为系统服务:1scm-server.batinstall然后在系统服务里设置为自动启动,然后启动服务就可以通过http://localhost:8080访问了,默认用户名和密码都是scm

  10. centOS上安装最新git 2.4.0

    git地址:https://www.kernel.org/pub/software/scm/git/1.先安装一堆依赖yuminstallcurlcurl-develzlib-developenssl-develperlcpioexpat-develgettext-develperl-ExtUtils-MakeMaker2.下载最新的git先切换到下载目录。我习惯下载到src目录cd/usr/lo

随机推荐

  1. static – 在页面之间共享数据的最佳实践

    我想知道在UWP的页面之间发送像’selectedItem’等变量的最佳做法是什么?创建一个每个页面都知道的静态全局变量类是一个好主意吗?

  2. .net – 为Windows窗体控件提供百分比宽度/高度

    WindowsForm开发的新手,但在Web开发方面经验丰富.有没有办法为Windows窗体控件指定百分比宽度/高度,以便在用户调整窗口大小时扩展/缩小?当窗口调整大小时,可以编写代码来改变控件的宽度/高度,但我希望有更好的方法,比如在HTML/CSS中.在那儿?

  3. 使用Windows Azure查询表存储数据

    我需要使用特定帐户吗?>将应用程序部署到Azure服务后,如何查询数据?GoogleAppEngine有一个数据查看器/查询工具,Azure有类似的东西吗?>您可以看到的sqlExpressintance仅在开发结构中,并且一旦您表示没有等效,所以请小心使用它.>您可以尝试使用Linqpad查询表格.看看JamieThomson的thispost.

  4. windows – SetupDiGetClassDevs是否与文档中的设备实例ID一起使用?

    有没有更好的方法可以使用DBT_DEVICEARRIVAL事件中的数据获取设备的更多信息?您似乎必须指定DIGCF_ALLCLASSES标志以查找与给定设备实例ID匹配的所有类,或者指定ClassGuid并使用DIGCF_DEFAULT标志.这对我有用:带输出:

  5. Windows Live ID是OpenID提供商吗?

    不,WindowsLiveID不是OpenID提供商.他们使用专有协议.自从他们的“测试版”期结束以来,他们从未宣布计划继续它.

  6. 如果我在代码中进行了更改,是否需要重新安装Windows服务?

    我写了一个Windows服务并安装它.现在我对代码进行了一些更改并重新构建了解决方案.我还应该重新安装服务吗?不,只需停止它,替换文件,然后重新启动它.

  7. 带有双引号的字符串回显使用Windows批处理输出文件

    我正在尝试使用Windows批处理文件重写配置文件.我循环遍历文件的行并查找我想要用指定的新行替换的行.我有一个’函数’将行写入文件问题是%Text%是一个嵌入双引号的字符串.然后失败了.可能还有其他角色也会导致失败.如何才能使用配置文件中的所有文本?尝试将所有“在文本中替换为^”.^是转义字符,因此“将被视为常规字符你可以尝试以下方法:其他可能导致错误的字符是:

  8. .net – 将控制台应用程序转换为服务?

    我正在寻找不同的优势/劣势,将我们长期使用的控制台应用程序转换为Windows服务.我们为ActiveMQ使用了一个叫做java服务包装器的东西,我相信人们告诉我你可以用它包装任何东西.这并不是说你应该用它包装任何东西;我们遇到了这个问题.控制台应用程序是一个.NET控制台应用程序,默认情况下会将大量信息记录到控制台,尽管这是可配置的.任何推荐?我们应该在VisualStudio中将其重建为服务吗?我使用“-install”/“-uninstall”开关执行此操作.例如,seehere.

  9. windows – 捕获外部程序的STDOUT和STDERR *同时*它正在执行(Ruby)

    哦,我在Windows上:-(实际上,它比我想象的要简单,这看起来很完美:…是的,它适用于Windows!

  10. windows – 当我试图批量打印变量时,为什么我得到“Echo is on”

    我想要执行一个简单的批处理文件脚本:当我在XP中运行时,它给了我预期的输出,但是当我在Vista或Windows7中运行它时,我在尝试打印值时得到“EchoisOn”.以下是程序的输出:摆脱集合表达式中的空格.等号(=)的两侧可以并且应该没有空格BTW:我通常在@echo关闭的情况下启动所有批处理文件,并以@echo结束它们,所以我可以避免将代码与批处理文件的输出混合.它只是使您的批处理文件输出更好,更清洁.

返回
顶部