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

后端 未结 3 1234
无人共我
无人共我 2021-02-10 14:24

I have the service name for a windows service in delphi, and I know how to get the handle from that as well. What I need to do is stop a service, and if the stop fails for some

相关标签:
3条回答
  • 2021-02-10 14:59

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

    Here's the function, for your own reference. It 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 讨论(0)
  • 2021-02-10 15:09

    Please note I have only accepted this solution so that a full delphi code solution is accepted, all due thanks to Jk though for pointing me on the correct path.

    --

    Ok, I've been able to figure out how to use the answer by Jk and have come up with this solution in delphi.

    For reference, this is the link provided by Jk:

    QueryServiceStatusEx

    My Solution:

    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 naming and other necessities are included.

    0 讨论(0)
  • 2021-02-10 15:14

    QueryServiceStatusEx?

    0 讨论(0)
提交回复
热议问题