Solved

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

Posted on 2003-12-02
5
512 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

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

746 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now