我有一个用Delphi编写的Windows服务.它偶尔使用的第三方资源之一会被破坏,我发现修复这种情况的唯一方法就是退出并重新启动程序.我可以检测到程序中资源何时被破坏,我可以告诉Windows在服务停止后重新启动服务,但我无法弄清楚如何让服务告诉自己停止服务.
该计划非常简单.我用似乎正常的方式创建了一个服务应用程序.我有一个TService的子类来管理服务,而所有的功能都发生在一个单独的线程中.TService子类几乎只管理子线程的执行,并且在子线程中我会检测到损坏.
作为参考,这是服务和子线程的头信息.
type TScannerThread = class(TThread) private Scanner : TScanner; DefaultDir : String; ImageDir : String; procedure CheckScanner; public Parent : TComponent; procedure Execute; override; end; TCardScanSvc = class(TService) procedure ServiceCreate(Sender: TObject); procedure ServiceExecute(Sender: TService); procedure ServiceStart(Sender: TService; var Started: Boolean); procedure ServiceStop(Sender: TService; var Stopped: Boolean); procedure ServicePause(Sender: TService; var Paused: Boolean); procedure ServiceContinue(Sender: TService; var Continued: Boolean); private ScannerThread : TScannerThread; public function GetServiceController: TServiceController; override; end; var CardScanSvc : TCardScanSvc;
在GUI应用程序中,我调用Application.Terminate,但TServiceApplication似乎没有该方法.我可以终止子线程,但主线程从未注意到,Windows认为该服务仍在运行.我真的想不起其他许多尝试.
该程序最初是在Delphi 5中创建的,我目前正在使用Delphi 2007,以防万一.
使用mghie的代码,我可以停止服务,但Windows只会在意外失败时重启服务,而不是正常停止服务.我要做的是创建一个单独的服务应用程序,如果有问题则将第一个信号作为第二个信号,然后让第二个信号重新启动第一个.
服务停止本身是没有问题的 - 我只是尝试使用自己的一个服务,用Delphi 4编写(不使用TService类).以下例程适用于我:
procedure TTestService.StopService; var Scm, Svc: SC_Handle; Status: SERVICE_STATUS; begin Scm := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS); if Scm <> 0 then begin Svc := OpenService(Scm, PChar(ServiceName), SERVICE_ALL_ACCESS); if Svc <> 0 then begin ControlService(Svc, SERVICE_CONTROL_STOP, Status); // handle Status.... CloseServiceHandle(Svc); end; CloseServiceHandle(Scm); end; end;
您需要检查它是否也适用于您的工作线程.