Link to home
Start Free TrialLog in
Avatar of Moonstyler
Moonstyler

asked on

Do certain things depending on whether or not a certain process is running.

Basically, what I've got is a program that does something or something else depending on whether or not MSN Messenger is running.

The image name of MSN Messenger is msnmsgr.exe

What I'd like is some source code that does something like

begin
if (msnmsgr.exe is in the tasklist) then
 ShowMessage('MSN Messenger is running');
else
 ShowMessage('MSN Messenger is not running');
end;

or something where the outcome is the same.

Thanks for all the help, guys!
Avatar of sftweng
sftweng

From the JEDI JCL, the RunningProcessesList function. See http://www.delphi-jedi.org.

Returns a list of all running processes.
function RunningProcessesList(const List: TStrings; FullPath: Boolean = True): Boolean;

Unit

JclSysInfo

Parameters

const List: TStrings

The list which is filled with the names of all running processes. Note that if this function is executed NT 3 or NT 4 the Objects property of the list contains INVALID_HANDLE_VALUE, on all other systems the Objects property is filled with the ToolHelp Process ID which you can use to further investigate the process.

FullPath: Boolean = True

If True the names of processes in the list are expanded to include the full path of the executable file. If False only the process name (filename of the executable) is put in the list.

Return Value

If the function succeeds it returns True, otherwise it returns False. In the latter case the contents of the list is undefined.

Description

RunningProcessesList fills the List parameter with a list of all running processes.

Notes

On Windows NT/2000 there exists two processes with PIDs 0 and 2 (8 on Windows 2000) which do not map to an executable image file. The names of these processes are fabricated by the routine as "System Idle Process" and "System Process" respectively.

Quick Info

 Donator: Petr Vones

Project JEDI (http:
Moonstyler hope this might help

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, Forms,
  Psapi, tlhelp32, StdCtrls, Dialogs;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure Win9xProcessList(list : TStringList) ;
    procedure WinNTProcessList(list : TStringList) ;
    procedure GetProcessList(var list : TStringList) ;
    function IsExeRunning(fileName : string) : boolean;

  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  if IsExeRunning('msnmsgr.exe') then
     ShowMessage('Msn running')
  else
     ShowMessage('Msn Not running');
end;

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

procedure TForm1.WinNTProcessList(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 TForm1.GetProcessList(var list : TStringList) ;
var
  vi : TOSVersionInfo ;
begin
  if list = nil then Exit ;
  vi.dwOSVersionInfoSize := sizeof(TOSVersionInfo) ;
  GetVersionEx(vi) ;
  case vi.dwPlatformId of
    VER_PLATFORM_WIN32_WINDOWS : Win9xProcessList(list) ;
    VER_PLATFORM_WIN32_NT : WinNTProcessList(list) ;
  end
end;

function TForm1.IsExeRunning(fileName : string) : boolean;
var
  i : integer ;
  processList : TStringList;
begin
  processList := TStringList.Create;
  try
    GetProcessList(processList) ;
    result := false;
    if processList = nil then exit;
    for i := 0 to processList.Count - 1 do
    begin
      if CompareText(ExtractFileName(processList.Strings[i]),fileName) = 0 then
      begin
        result := true;
        break;
      end;
    end;
  finally
    processList.Free ;
  end;
end;

end.
ASKER CERTIFIED SOLUTION
Avatar of Kalroth
Kalroth

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Moonstyler

ASKER

By Jove it works!

That is excellent!

Now, two things.

How do I do both an accept and an assist on this site?
Could you (Kalroth) please explain how your code actually works?
I'm relatively new to Delphi, you see, and this info would be particularly useful.

You don't need to, you'll still get the points, but I would appreciate it.

Thanks again guys!

Moonstyler
First off, sahilkhan20's code is both Windows 95/98/ME and Windows NT/2000/XP/2003 compatible.
My example uses psapi.dll which I believe is limited to the NT/2000/XP/2003 platforms.
 ( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/perfmon/base/process_status_helper.asp )

As for the code:

First it returns all running processes using EnumProcesses().
 ( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/perfmon/base/enumprocesses.asp )

It then tries to open each process with OpenProcess() and return a handle to it, if successful.
 ( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/openprocess.asp )  

If it was successful, then it'll enumerate all modules in that process using EnumProcessModules()
 ( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/perfmon/base/enumprocessmodules.asp )

If that also was successful, then it'll fetch the modulename with full path using GetModuleFileNameEx()
 ( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getmodulefilename.asp )

Then it's just a simple case-insensitive comparison of the filename of the modulename against the wanted filename using lstricmp(), which will exit on success and leave the process handle open, which is why it's important that you close it yourself.

You can find the MSDN on the whole thing here: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/perfmon/base/enumerating_all_modules_for_a_process.asp

Kalroth