delphi - 如何重新启动用 Delphi 编写的 Windows 服务应用程序?

标签 delphi winapi windows-services

我有一个用 Delphi 编写的 Windows 服务。它使用的第三方资源之一偶尔会损坏,我发现解决此问题的唯一方法是退出并重新启动程序。我可以从程序中检测资源何时损坏,我可以告诉 Windows 在服务停止后重新启动服务,但我不知道如何让服务告诉自己停止。

程序非常简单。我以似乎正常的方式创建了一个服务应用程序。我有一个 TService 的子类来管理服务,而所有功能都在一个单独的线程中发生。 TService 子类几乎只管理子线程的执行,并且我会在子线程中检测损坏。

作为引用,这里是服务和子线程的 header 信息。

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;

您需要检查它是否也适用于您的工作线程。

关于delphi - 如何重新启动用 Delphi 编写的 Windows 服务应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/667588/

相关文章:

delphi - DataModule 在主窗体之前创建

delphi - 如何从Delphi向POS打印机发送控制命令

c++ - 如何在 C++ 中将图标放在按钮上?

c# - Windows 服务 : Managed Compatibility Mode does not support Edit and Continue

c# - 如何从服务接收 OutputDebugString?

c# - 如何异步调用我的 WCF 服务?

delphi - 自定义 QuickSort 实现中的 SIGSEGV

delphi - 如何获得笔记本电脑或台式机支持的最大内存大小?

windows - 为什么鼠标在 DISCL_EXCLUSIVE | 中消失了? DISCL_FOREGROUND 模式?

windows - 如何使用设备实例句柄获取 USB 设备句柄?