我在delphi中有一个Windows服务的服务名称,我也知道如何从中获取句柄.我需要做的是停止服务,如果由于某种原因停止失败,我需要终止与服务相关的进程.问题是我有多个服务从同一个可执行文件运行,所以我不能使用可执行文件名来终止进程.这意味着我需要进程ID来终止正确的关联进程.如何从服务名称或句柄中获取此id或某种方式来终止正确的进程?
QueryServiceStatusEx
?
请注意我只接受了这个解决方案,以便接受完整的delphi代码解决方案,所有这一切都要归功于Jk,因为我指的是正确的路径.
-
好的,我已经能够弄清楚如何使用Jk的答案,并在delphi中提出了这个解决方案.
作为参考,这是Jk提供的链接:
QueryServiceStatusEx
我的解决方案
unit Demo; interface uses Windows, Forms, SysUtils, StdCtrls, WinSvc, Controls, Classes; type //Form for basic demo usage TForm6 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); end; //Record defined for use as return buffer _SERVICE_STATUS_PROCESS = record dwServiceType: DWORD; dwCurrentState: DWORD; dwControlsAccepted: DWORD; dwWin32ExitCode: DWORD; dwServiceSpecificExitCode: DWORD; dwCheckPoint: DWORD; dwWaitHint: DWORD; dwProcessId: DWORD; dwServiceFlags: DWORD; end; //Function Prototype function QueryServiceStatusEx( SC_HANDLE: SC_Handle; SC_STATUS_TYPE: Cardinal; out lpBuffer: _SERVICE_STATUS_PROCESS; cbBufSize: DWORD; out pcbBytesNeeded: LPDWORD ): BOOL; stdcall; //internal setup function function GetPid(sService: String; sMachine: String = '') : Cardinal; var Form6: TForm6; implementation {$R *.dfm} const // windows api library advapi32 = 'advapi32.dll'; //define the api call function QueryServiceStatusEx; external advapi32 name 'QueryServiceStatusEx'; //for demo usage procedure TForm6.Button1Click(Sender: TObject); begin Memo1.Lines.Add(IntToStr(Integer(GetPid('Service')))) end; function GetPid(sService: String; sMachine: String = '') : Cardinal; var schm, schs: SC_Handle; SC_STATUS_TYPE: Cardinal; lpBuffer: _SERVICE_STATUS_PROCESS; cbBufSize: DWORD; pcbBytesNeeded: LPDWORD; begin //open the service manager (defined in WinSvc) schm := OpenSCManager(PChar(sMachine), nil, SC_MANAGER_CONNECT); //set the status type to SC_STATUS_PROCESS_INFO //this is currently the only value supported SC_STATUS_TYPE := $00000000; //set the buffer size to the size of the record cbBufSize := sizeof(_SERVICE_STATUS_PROCESS); if (schm>0) then begin //grab the service handle schs := OpenService(schm, PChar(sService), SERVICE_QUERY_STATUS); if (schs>0) then begin //call the function QueryServiceStatusEx( schs, SC_STATUS_TYPE, lpBuffer, cbBufSize, pcbBytesNeeded); CloseServiceHandle(schs); end; CloseServiceHandle(schm); end; Result := lpBuffer.dwProcessId; end; end.
请注意,并非包括所有外部命名和其他必需品.