有时我们的一些操作,需要先关掉一些程序才能继续执行,那怎么才能判断一个程序在运行呢?
下面介绍一种是用系统快照的方式来实现判断一个程序是否运行。
(一)快照函数介绍
CreateToolhelp32Snapshot函数为指定的进程、进程使用的堆[HEAP]、模块[MODULE]、线程[THREAD])建立一个快照[snapshot]。
HANDLE WINAPI CreateToolhelp32Snapshot(
DWORD dwFlags, //用来指定“快照”中需要返回的对象,可以是TH32CS_SNAPPROCESS等
DWORD th32ProcessID //一个进程ID号,用来指定要获取哪一个进程的快照,当获取系统进程列表或获取当前进程快照时可以设为0
);
参数:
dwFlags
[输入]指定快照中包含的系统内容,这个参数能够使用下列数值(常量)中的一个或多个。
TH32CS_INHERIT - 声明快照句柄是可继承的。
TH32CS_SNAPALL - 在快照中包含系统中所有的进程和线程。
TH32CS_SNAPHEAPLIST - 在快照中包含在th32ProcessID中指定的进程的所有的堆。
TH32CS_SNAPMODULE - 在快照中包含在th32ProcessID中指定的进程的所有的模块。
TH32CS_SNAPPROCESS - 在快照中包含系统中所有的进程。
TH32CS_SNAPTHREAD - 在快照中包含系统中所有的线程。
Const TH32CS_SNAPHEAPLIST = &H1
Const TH32CS_SNAPPROCESS = &H2
Const TH32CS_SNAPTHREAD = &H4
Const TH32CS_SNAPMODULE = &H8
Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE)
Const TH32CS_INHERIT = &H80000000
th32ProcessID
[输入]指定将要快照的进程ID。如果该参数为0表示快照当前进程。该参数只有在设置了TH32CS_SNAPHEAPLIST或者TH32CS_SNAPMODULE后才有效,在其他情况下该参数被忽略,所有的进程都会被快照。
返回值:
调用成功,返回快照的句柄,调用失败,返回INVALID_HANDLE_VALUE 。
备注:
使用GetLastError函数查找该函数产生的错误状态码。
(二)快照函数如何使用
uses TLHelp32;
procedure TForm1.Button1Click(Sender: TObject);
var
processName: string;
ProcessID: integer;
ListLoop: Boolean;
FsnapShotHandle: Thandle;
FProcessEntry32: TProcessEntry32;
begin
Fsnapshothandle := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwsize := SizeOF(FProcessEntry32);
Listloop := Process32First(FSnapshotHandle, FProcessEntry32);
while Listloop do
begin
processName := FprocessEntry32.szExeFile;
ProcessID := FProcessEntry32.th32ProcessID; // 我写到列表框中了,你可以根据需要自己改
listbox1.Items.Add('Process NAME:' + processName);
ListLoop := Process32Next(FSnapshotHandle, FprocessEntry32);
end;
end;
(三)完整的示例
下面是一个完整示例来介绍如何使用这些api函数来实现想要实现的功能
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
btn1: TButton;
mmo1: TMemo;
btn2: TButton;
procedure FormCreate(Sender: TObject);
procedure btn1Click(Sender: TObject);
procedure btn2Click(Sender: TObject);
private
FListTFList;
function EnumProcess(hHwnd: HWND; lParam : integer): boolean;
function GetInstallPathByID(AID: Integer):string;
public
end;
var
Form1: TForm1;
implementation
Uses
Tlhelp32, PSAPI, Registry;
{$R *.dfm}
function TForm1.EnumProcess(hHwnd: HWND; lParam : integer): boolean;
var
pPid : DWORD;
title, ClassName : string;
begin
if (hHwnd=NULL) then
begin
result := false;
end
else
begin
//additional functions to get more
//information about a process.
//get the Process Identification number.
GetWindowThreadProcessId(hHwnd,pPid);
//set a memory area to receive
//the process class name
SetLength(ClassName, 255);
//get the class name and reset the
//memory area to the size of the name
SetLength(ClassName,GetClassName(hHwnd,PChar(className),Length(className)));
SetLength(title, 255);
//get the process title; usually displayed
//on the top bar in visible process
SetLength(title, GetWindowText(hHwnd, PChar(title), Length(title)));
//Display the process information
//by adding it to a list box
Form1.mmo1.Lines.Add('Class Name = ' + className +'; Title = ' + title +'; HWND = ' + IntToStr(hHwnd) +'; Pid = ' + IntToStr(pPid));
Result := true;
end;
end;
function TForm1.GetInstallPathByID(AID: Integer):string;
var
pid: dword;
hnd: THandle;
hModuleSnap: THandle;
me32: MODULEENTRY32;
begin
hnd := openprocess(PROCESS_ALL_ACCESS, FALSE, AID);
hModuleSnap := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
if hModuleSnap = INVALID_HANDLE_VALUE then
exit;
me32.dwSize := SizeOf(MODULEENTRY32);
if Module32First(hModuleSnap, me32) then
begin
repeat
FList.Add(format('MODULE NAME: %s', [me32.szModule]));
FList.Add(format('executable: %s', [me32.szExePath]));
FList.Add(format('process id: %d', [me32.th32ProcessID]));
FList.Add(format('ref count(g):%d', [me32.GlblcntUsage]));
FList.Add(format('ref count(p):%d', [me32.ProccntUsage]));
FList.Add(format('base address:%d', [DWORD(me32.modBaseAddr)]));
FList.Add(format('base size: %d', [me32.modBaseSize]));
until not Module32Next(hModuleSnap, me32);
end;
CloseHandle(hModuleSnap);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
found: Boolean;
FSnapshotHandle: THandle;
lppe: TProcessEntry32;
strVer: string;
I: Integer;
begin
FList := TFList.Create;
FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); //CreateToolhelp32Snapshot函数得到进程快照
lppe.dwSize := Sizeof(lppe); //初始化
found := Process32First(FSnapshotHandle, lppe); //Process32First 得到一个系统快照里第一个进程的信息
while found do
begin
if SameText(ExtractFileName(lppe.szExeFile), 'GCPHost.exe') then
begin
FList.Add(ExtractFileName(lppe.szExeFile));//进程名称
FList.Add(IntToStr(lppe.th32ProcessID));//进程ID
end;
found := Process32Next(FSnapshotHandle, lppe);
end;
CloseHandle(FSnapshotHandle);
Self.Caption:='当前系统共有'+''+inttostr(FList.count div 3)+''+'个delphi进程' ;
end;
procedure TForm1.btn1Click(Sender: TObject);
begin
if FList.IndexOf('11') <> -1 then
ShowMessage('delphi XE2正在运行');
mmo1.Lines.AddStrings(FList);
end;
procedure TForm1.btn2Click(Sender: TObject);
var
han: HWND;
begin
han := FindWindow('TAppBuilder', nil);
EnumProcess(han,0);
end;
end.