summerset
asked on
Find if a program is running by exe name not handle?
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
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
listening :-)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Hi,
This code should work for all windows versions.
(if not, let me know)
tas
//************************ ********** ********** **//
Uses
Psapi, tlhelp32;
procedure CreateWin9xProcessList(Lis t : TStringList) ;
var
hSnapShot : THandle;
ProcInfo : TProcessEntry32;
begin
if List = nil then Exit ;
hSnapShot := CreateToolHelp32Snapshot(T H32CS_SNAP PROCESS, 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.szExeFil e) ;
end ;
CloseHandle(hSnapShot) ;
end ;
end ;
procedure CreateWinNTProcessList(Lis t : 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_ INFORMATIO N or
PROCESS_VM_READ,
false,
PIDArray[I]) ;
if (hProcess <> 0) then
begin
EnumProcessModules(hProces s, @hMod, sizeof(hMod), cb) ;
GetModuleFilenameEx(hProce ss,hMod,Mo duleName,s izeof(Modu leName));
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(Lis t) ;
VER_PLATFORM_WIN32_NT : CreateWinNTProcessList(Lis t) ;
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(ExtractFileNam e(MyProcLi st.Strings [i]),FileN ame) = 0 then result := true
end else
if CompareText(MyProcList.Str ings[i],Fi leName) = 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.ex e',true) then
ShowMessage('Notepad is running')
else
ShowMessage('Notepad is not running');
end;
This code should work for all windows versions.
(if not, let me know)
tas
//************************
Uses
Psapi, tlhelp32;
procedure CreateWin9xProcessList(Lis
var
hSnapShot : THandle;
ProcInfo : TProcessEntry32;
begin
if List = nil then Exit ;
hSnapShot := CreateToolHelp32Snapshot(T
if (hSnapShot <> THandle(-1)) then
begin
ProcInfo.dwSize := sizeof(ProcInfo) ;
if (Process32First(hSnapshot,
begin
List.Add( ProcInfo.szExeFile) ;
while (Process32Next(hSnapShot, ProcInfo)) do
List.Add(ProcInfo.szExeFil
end ;
CloseHandle(hSnapShot) ;
end ;
end ;
procedure CreateWinNTProcessList(Lis
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_
PROCESS_VM_READ,
false,
PIDArray[I]) ;
if (hProcess <> 0) then
begin
EnumProcessModules(hProces
GetModuleFilenameEx(hProce
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
VER_PLATFORM_WIN32_NT : CreateWinNTProcessList(Lis
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(ExtractFileNam
end else
if CompareText(MyProcList.Str
if result then break;
end;
finally
MyProcList.Free ;
end;
end;
// Example : Is Notepad.exe running ?
procedure TForm1.Button1Click(Sender
begin
if EXE_ISRunning('c:\Windows\
ShowMessage('Notepad is running')
else
ShowMessage('Notepad is not running');
end;
ASKER
Thank you!
-S
-S
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.
ASKER
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
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