如何重新启动用Delphi编写的Windows服务应用程序? [英] How can I restart a Windows service application written in Delphi?
问题描述
程序很简单。我创建了一个似乎是正常方式的服务应用程序。我有一个子类的TService来管理服务,而所有的功能发生在一个单独的线程中。 TService子类几乎只是管理子线程的执行,它在subthread中,我将检测到损坏。
为了参考,这里是标题信息服务和子线程。
键入
TScannerThread = class(TThread)
private
扫描仪: TScanner;
DefaultDir:String;
ImageDir:String;
程序CheckScanner;
public
父级:TComponent;
程序执行;覆盖
结束
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
扫描仪线程:TScannerThread;
public
函数GetServiceController:TServiceController;覆盖
结束
var
CardScanSvc:TCardScanSvc;
在GUI应用程序中,我将调用Application.Terminate,但是TServiceApplication似乎没有那个方法。我可以终止subthread,但主线程从来没有注意到,Windows认为该服务仍在运行。我不能真的想到很多其他的尝试。
该程序最初是在Delphi 5中创建的,目前我正在使用Delphi 2007,以防止差异。
编辑:
使用mghie的代码,可以停止服务,但Windows将仅在意外失败时重新启动服务,而不是正常停止。我要做的是做一个单独的服务应用程序,如果有问题,第一个信号是第二个信号,然后重新启动第二个。
服务停止是没有问题的 - 我刚刚尝试使用我自己的一个服务,用Delphi 4编写(不使用 TService 类)。以下例程适用于我:
过程TTestService.StopService;
var
Scm,Svc:SC_Handle;
状态:SERVICE_STATUS;
begin
Scm:= OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS);
如果Scm<> 0然后开始
Svc:= OpenService(Scm,PChar(ServiceName),SERVICE_ALL_ACCESS);
如果Svc 0然后开始
ControlService(Svc,SERVICE_CONTROL_STOP,Status);
// handle Status ....
CloseServiceHandle(Svc);
结束
CloseServiceHandle(Scm);
结束
结束
您需要检查它是否也可以从您的工作线程工作。
I have a Windows service written in Delphi. One of the third-party resources it uses occasionally gets corrupted, and the only way I've found to fix the situation is to exit and restart the program. I can detect when the resource is corrupted from within the program, and I can tell Windows to restart the service after it stops, but I can't figure out how to have the service tell itself to stop.
The program is pretty simple. I created a service application in what seems to be the normal way. I have a subclass of TService to manage the service, while all of the functionality occurs in a separate thread. The TService subclass pretty much just manages the execution of the subthread, and it's in the subthread that I would be detecting the corruption.
For reference, here's the header info for the service and subthread.
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;
In a GUI application, I'd call Application.Terminate, but TServiceApplication doesn't seem to have that method. I can terminate the subthread, but the main thread never notices, and Windows thinks the service is still running. I can't really think of much else to try.
The program was originally created in Delphi 5, and I'm currently using Delphi 2007, in case that makes a difference.
Edit:
With mghie's code, I can stop the service, but Windows will only restart the service if it fails unexpectedly, not if it's stopped normally. What I'm going to do is make a separate service application, have the first signal the second if it has problems, and then have the second restart the first.
There is no problem having the service stop itself - I just tried with one of my own services, written with Delphi 4 (without using the TService class). The following routine works for me:
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;
You need to check whether it will also work from your worker thread.
这篇关于如何重新启动用Delphi编写的Windows服务应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!