How can I find the process id from the service name / descriptor in Delphi?

I have a service name for the windows service in delphi, and I know how to get a handle from this. I need to stop the service, and if the stop fails for some reason, I need to kill the process associated with the service. The problem is that I have several services running from the same executable, so I cannot use the name of the executable to kill the process. This means that I need a process identifier to kill the corresponding related process. How can I get this identifier or some way to kill the correct process from the service name or descriptor?

+4
source share
3 answers

Please note that I made this decision only to make a complete decision for Delphi code, thanks to JK, although to point to the correct path.

-

Well, I was able to figure out how to use the Jk answer and come up with this solution in delphi.

For reference, this is the link provided by Jk:

QueryServiceStatusEx

My decision:

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. 

Please note that not all external names and other essentials are included.

+6
source
+8
source

Or use DSiWin32 for many useful features , including DSiGetProcessID. This code was written by user (and programmer) StackOverflow).

Here's a feature for your own link. He will give you what you are looking for:

 //Retrieves ID of the specified process. Requires Toolhelp API. // @returns False if ID cannot be retrieved. Check GetLastError - if it is 0, process // doesn't exist; otherwise it contains the Win32 error code. // @author gabr // @since 2004-02-12 // function DSiGetProcessID(const processName: string; var processID: DWORD): boolean; var hSnapshot: THandle; procEntry: TProcessEntry32; begin Result := false; hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if hSnapshot = 0 then Exit; try procEntry.dwSize := Sizeof(procEntry); if not Process32First(hSnapshot, procEntry) then Exit; repeat if AnsiSameText(procEntry.szExeFile, processName) then begin processID := procEntry.th32ProcessID; Result := true; break; // repeat end; until not Process32Next(hSnapshot, procEntry); finally DSiCloseHandleAndNull(hSnapshot); end; end; { DSiGetProcessID } 
0
source

All Articles