We help IT Professionals succeed at work.

Find if a program is running by exe name not handle?

summerset
summerset asked
on
Hello,

I have a customer that I made a custom app for. I have a timer on the form that does specific tasks every 1 second. One of the new tasks added is that the customer can set the path to an application that will get launched at a specific time. Since I won't know in advance the title of the application, I will need to find if a path to the exe file has been set, and check if it is running. If it is running do nothing. I would shell execute it otherwise. Because I will not know the handle, I cannot use FindWindow -- I will only have the path set to the executable, and I have noticed that other methods do not work with all 32 bit versions of Windows -- 95 thru 2000.

My question is - how can I (by knowing only the path to the executable of the other program) find out if it is running or not -- in all 32 bit versions of Windows? Does anybody have a sample of how this can be done?

Thank you in advance.

-S
Comment
Watch Question

Commented:
listening :-)
Commented:
You can try my free unit:

http://www.madshi.net/enumStuff.zip

This unit can enumerate processes in all 32bit versions of Windows. For each process you'll get the file name and processID. The unit runs under D4-D6.

Regards, Madshi.

Commented:
Hi,

This code should work for all windows versions.
(if not, let me know)

tas

//**********************************************//


Uses
  Psapi, tlhelp32;

procedure CreateWin9xProcessList(List : TStringList) ;
var
  hSnapShot : THandle;
  ProcInfo : TProcessEntry32;
begin
  if List = nil then Exit ;
  hSnapShot := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if (hSnapShot <> THandle(-1)) then
  begin
    ProcInfo.dwSize := sizeof(ProcInfo) ;
    if (Process32First(hSnapshot, ProcInfo)) then
    begin
     List.Add( ProcInfo.szExeFile) ;
     while (Process32Next(hSnapShot, ProcInfo)) do
      List.Add(ProcInfo.szExeFile) ;
    end ;
    CloseHandle(hSnapShot) ;
  end ;
end ;

procedure CreateWinNTProcessList(List : TStringList) ;
var
  PIDArray : array [0..1023] of DWORD ;
  cb : DWORD ;
  I : integer ;
  ProcCount : integer ;
  hMod : HMODULE ;
  hProcess : THandle ;
  ModuleName : array [0..300] of char ;
begin
  if List = nil then Exit ;
  EnumProcesses(@PIDArray, sizeof(PIDArray), cb) ;
  ProcCount := cb div sizeof(DWORD) ;
  for I := 0 to ProcCount-1 do
  begin
    hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or
    PROCESS_VM_READ,
    false,
    PIDArray[I]) ;
    if (hProcess <> 0) then
    begin
      EnumProcessModules(hProcess, @hMod, sizeof(hMod), cb) ;
      GetModuleFilenameEx(hProcess,hMod,ModuleName,sizeof(ModuleName));
      List.Add(ModuleName);
      CloseHandle(hProcess);
    end;
  end;
end;

procedure GetProcessList(Var List : TStringList) ;
var ovi : TOSVersionInfo ;
begin
  if List = nil then Exit ;
  ovi.dwOSVersionInfoSize := sizeof(TOSVersionInfo) ;
  GetVersionEx(ovi) ;
  case ovi.dwPlatformId of
    VER_PLATFORM_WIN32_WINDOWS : CreateWin9xProcessList(List) ;
    VER_PLATFORM_WIN32_NT : CreateWinNTProcessList(List) ;
  end
end;

function EXE_ISRunning(FileName : String; fullpath : boolean) : boolean;
var
  i : integer ;
  MyProcList : TStringList;
begin
 MyProcList := TStringList.Create;
 try
   GetProcessList(MyProcList) ;
   result := false;
   if MyProcList = nil then Exit;
    for i := 0 to MyProcList.Count - 1 do
    begin
      if not fullpath then
      begin
       if CompareText(ExtractFileName(MyProcList.Strings[i]),FileName) = 0 then result := true
      end else
       if CompareText(MyProcList.Strings[i],FileName) = 0 then result := true;
     if result then break;
    end;
  finally
   MyProcList.Free ;
 end;
end;


// Example : Is Notepad.exe running ?

procedure TForm1.Button1Click(Sender: TObject);
begin
 if EXE_ISRunning('c:\Windows\notepad.exe',true) then
    ShowMessage('Notepad is running')
 else
    ShowMessage('Notepad is not running');
end;




Author

Commented:
Thank you!
-S

Commented:
Thanx for the points. BTW, the code posted by Tasomia should also work fine under all systems, however, it needs Microsoft's dll "PsApi.dll" on NT systems. This is not included in all installations, so you would have to distribute the PsApi.dll with your application, quite ugly. My unit doesn't need PsApi.dll.

Author

Commented:
Thanks, Madshi!

I wish I had more time to go through the whole thing (very hectic schedule). Your code is excellent. The only thing I would ask or suggest would be to include a quick calling sample for each function -- or atleast the important ones as a time saver.

Again -- thank you so much.

-Summerset

Explore More ContentExplore courses, solutions, and other research materials related to this topic.