Solved

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

Posted on 2003-12-02
5
518 Views
Last Modified: 2010-04-05
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!
0
Comment
Question by:Moonstyler
5 Comments
 
LVL 7

Expert Comment

by:sftweng
ID: 9857035
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:
0
 
LVL 1

Expert Comment

by:sahilkhan20
ID: 9857456
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.
0
 
LVL 2

Accepted Solution

by:
Kalroth earned 150 total points
ID: 9858294
An easier/smaller version could be something like the code below.
It'll also return the handle to the process. Remember to close it after use.
If you don't want that, then you can modify the function easily to close the handle after the process has been found.

Usage example:

(** EXAMPLE CODE **)

var
  ProcessID : THandle;
begin
  ProcessID := FindProcess('msnmsgr.exe');
  if ProcessID <> 0 then
  begin
    ShowMessage('Messenger is running.')
     CloseHandle(ProcessID);
  end else begin
    ShowMessage('Messenger is not running!');
    // No need to close the handle, since the process was never found.
  end;
end;

(** /EXAMPLE CODE**)

(** CODE **)

uses
  PsAPI;

function FindProcess(const strModuleFilename: string): THandle;
const
  cnMAXPROCESS = 512;
var
  arrProcess: array[0 .. cnMAXPROCESS-1] of DWORD;
  hndModule: HMODULE;
  dwNeeded: DWORD;
  strProcessName: array[0 .. MAX_PATH-1] of Char;
  iCnt: Integer;
begin
  if EnumProcesses(@arrProcess, SizeOf(arrProcess), dwNeeded) then
    for iCnt := 0 to dwNeeded div SizeOf(DWORD) - 1 do
    begin
      Result := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ or SYNCHRONIZE, False, arrProcess[iCnt]);
      if Result <> 0 then
      begin
        if EnumProcessModules(Result, @hndModule, SizeOf(hndModule), dwNeeded) then
        begin
          GetModuleFileNameEx(Result, hndModule, strProcessName, SizeOf(strProcessName));
          if lstrcmpi(PChar(ExtractFilename(strProcessName)), PChar(strModuleFilename)) = 0 then
            Exit;
        end;
        CloseHandle(Result);
      end;
    end;
  Result := 0;
end;

(** /CODE **)
0
 

Author Comment

by:Moonstyler
ID: 9864382
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
0
 
LVL 2

Expert Comment

by:Kalroth
ID: 9865876
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
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Delphi TcxGrid group footer summary 3 316
Delphi cmd execution 6 67
Delphi XE10 Round Image 2 154
delphi parse string to params 3 136
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

840 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question