Get PID by exe name

I want to control some external applications by sending them messages / keystrokes. At present I’m using this code to get the PID, then using that to get the window handle.

function GetPIDbyProcessName(processName:String):integer;
var 
  GotProcess: Boolean; 
  tempHandle: tHandle; 
  procE: tProcessEntry32;
begin
  tempHandle:=CreateToolHelp32SnapShot(TH32CS_SNAPALL, 0); 
  procE.dwSize:=SizeOf(procE); 
  GotProcess:=Process32First(tempHandle, procE);
  {$B-} 
    if GotProcess and not SameText(procE.szExeFile, processName) then 
      repeat GotProcess := Process32Next(tempHandle, procE); 
      until (not GotProcess) or SameText(procE.szExeFile,processName); 
  {$B+}

  if GotProcess then 
    result := procE.th32ProcessID 
  else
    result := 0; // process not found in running process list

  CloseHandle(tempHandle);
end;

This works for most programs, but not all. Acrobat Reader is one. The PID I get back is not the one listed in the Apps section of Task Manager.

Is there a better way to get the PID by exe name?

Hi David,

Yeah, this can be a bit tricky.

Are you launching the instance of Acrobat Reader from your application? If so if you launch it using CreateProcess() then you will have a process handle and from that you can get the PID.

No, it would be launched by the user.

I did find (from a search here) a neat utility called WinDowse that does detect the correct PID when I hover it over the Acrobat window.

Maybe there is more than one process open called ‘Acrobat.exe’ and I need to find the one that has a window handle. It could be the first one I find is something else and because I stop looking at that point I never see the real one.

I ended up changing the functions to first get me a list of all PIDs with the specified exe name.

Then I iterate through those and try to get a handle for each one. As soon as one resolves (not zero) I use that as the result. So far it seems to work.