下面是本人的代码
function TfrmLogin.CheckApp():boolean;
var
i:integer;
strList:TStringList;
StrAppName:String;
blApp:integer;
{-----------------}
hand:thandle;
lppe:PROCESSENTRY32;
found:boolean;
begin
strList:=TStringList.Create;
MyIniFile:=TIniFile.Create(FilePath);
MyIniFile.ReadSectionValues('AppName',strList);
blApp:=0; for i:=0 to strList.Count -1 do begin
Hand:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
StrAppName:=Copy(StrList[i],Pos('=',StrList[i])+1,Length(StrList[i]));
if hand>0 then
lppe.dwSize:= sizeof(PROCESSENTRY32);
found:=Process32First(Hand,lppe);
while found do begin
if strpas(lppe.szExeFile)=StrAppName then begin
blApp:=blApp+1;
end;
found:=Process32next(Hand,lppe);
end;
closehandle(hand);
end;
for i:=0 to StrList.Count -1 do begin
if blApp<>strList.Count then begin
result:=false;
exit;
end
end;
result:=true;
end;
---------------------------
98系统下不能运行...请各位大哥帮忙~~!
请贴相关代码..谢谢
function TfrmLogin.CheckApp():boolean;
var
i:integer;
strList:TStringList;
StrAppName:String;
blApp:integer;
{-----------------}
hand:thandle;
lppe:PROCESSENTRY32;
found:boolean;
begin
strList:=TStringList.Create;
MyIniFile:=TIniFile.Create(FilePath);
MyIniFile.ReadSectionValues('AppName',strList);
blApp:=0; for i:=0 to strList.Count -1 do begin
Hand:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
StrAppName:=Copy(StrList[i],Pos('=',StrList[i])+1,Length(StrList[i]));
if hand>0 then
lppe.dwSize:= sizeof(PROCESSENTRY32);
found:=Process32First(Hand,lppe);
while found do begin
if strpas(lppe.szExeFile)=StrAppName then begin
blApp:=blApp+1;
end;
found:=Process32next(Hand,lppe);
end;
closehandle(hand);
end;
for i:=0 to StrList.Count -1 do begin
if blApp<>strList.Count then begin
result:=false;
exit;
end
end;
result:=true;
end;
---------------------------
98系统下不能运行...请各位大哥帮忙~~!
请贴相关代码..谢谢
解决方案 »
- cxGrid主从表问题,从表显示数据不全呀!
- 急!idimap4接收邮件的使用
- 用delphi更改桌面背景图片
- delphi2009自带的indy10.2.5 idtcpserver与idtcpclient传送记录类型时,中文显示乱码
- 爱国爱自己的同志请进!不进后悔!!!
- 两个adoquery如何实现关联?
- 有没有朋友用过intraweb中的IWDynamicchart这个控件,或者有没有相关的文档!
- 请问如何知道程序需要哪些库文件什么的
- 在线等...求救.XP下DELPHI7未响应....帮帮我,谢谢啦~
- 大家好啊,我是delphi初学者(我的qq:1138483.如果您是delphi的初学者,爱好者,加我哦)
- 一个关于软件界面设计的问题(是高手就进来,其余不要进了。)
- 查找文件findfirst函数中的FindData类型
一、函数介绍
在Windows系统中动态链接库kernel32.dll提供了获取和处理系统进程的许多接口函数,Delphi语言把这些函数接口封装到Tlhelp32.pas中,供Delphi用户开发过程调用。要详细了解相关知识可以查阅Tlhelp32.pas原文件和Windows SDK提供的帮助文件。其中同本文涉及的接口函数主要有CreateToolhelp32Snapshot、process32first、process32next、module32first、module32next五个函数以及TMODULEENTRY32、TPROCESSENTRY32两个数据结构。
1、CreateToolhelp32Snapshot该函数是要实现上述目的最核心的一个函数,它可以获取系统运行进程(Process)列表、线程(Thread)列表和指定运行进程的堆(Heap)列表、调用模块(Module)列表。如果函数运行成功将返回一个非零"Snapshot"句柄,通过该句柄调用相关WinAPI函数就可以实现上述目的,其函数格式为:
HANDLE WINAPI CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID);
参数说明:dwFlags参数:对函数建立的"Snapshot"所包含的列表类型,可选项包括:TH32CS_SNAPHEAPLIST:所创建的Snapshot包含堆列表TH32CS_SNAPMODULE :所创建的Snapshot包含调用模块列表TH32CS_SNAPTHREAD :所创建的Snapshot包含线程列表;TH32CS_SNAPPROCESS :所创建的Snapshot包含进程列表;TH32CS_SNAPALL :所创建的Snapshot包含上述所有列表;th32ProcessID参数:进程句柄参数,可以为零表示当前进程,该参数只对dwFlags包含TH32CS_SNAPMODULE、TH32CS_SNAPHEAPLIST可选项时起作用。当dwFlags为TH32CS_SNAPPROCESS,th32ProcessID为零时函数得到系统的所有进程列表。
2、Process32First、Process32Next、Module32First、Module32Next这四个函数都是对"Snapshot"所包含的列表进行息获取,根据函数字面的英文意义,不难理解各函数的含义和区别,四个函数的格式分别为:
BOOL WINAPI Process32First(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);BOOL WINAPI Process32Next(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);BOOL WINAPI Module32First(HANDLE hSnapshot, LPMODULEENTRY32 lpme);BOOL WINAPI Module32Next(HANDLE hSnapshot, LPMODULEENTRY32 lpme);
3、TMODULEENTRY32、TPROCESSENTRY32
这两个数据结构中TPROCESSENTRY32是在Process32First、Process32Next两个函数所用到的数据结构,TMODULEENTRY32是在Module32First、Module32Next所用到的数据结构,两个数据结构分别如下:typedef struct tagPROCESSENTRY32 { DWORD dwSize; DWORD cntUsage; DWORD th32ProcessID; //进程句柄DWORD th32DefaultHeapID; DWORD th32ModuleID; DWORD cntThreads; DWORD th32ParentProcessID; LONG pcPriClassBase; DWORD dwFlags; char szExeFile[MAX_PATH]; } PROCESSENTRY32;typedef struct tagMODULEENTRY32 { DWORD dwSize; DWORD th32ModuleID; DWORD th32ProcessID; DWORD GlblcntUsage; DWORD ProccntUsage; BYTE * modBaseAddr; DWORD modBaseSize; HMODULE hModule; char szModule[MAX_MODULE_NAME32 + 1]; char szExePath[MAX_PATH]; //调用模块的含路径文件名} MODULEENTRY32;
在使用上面两个数据结构要特别强调一点,那就是函数使用这两个数据结构的变量时要先设置dwSize的值,分别用sizeof(TPROCESSENTRY32)和sizeof(TMODULEENTRY32)。
由于篇幅有限以上所提到的函数和数据结构可以查看Windows SDK帮助文件获取更详细的信息。
二、实现原理
要实现获得系统的所有运行进程和每个运行进程所调用模块的信息,实际上只要使用两重循环,外循环获取系统的所有进程列表,内循环获取每个进程所调用模块列表。用以下四组API调用实现:
1、创建系统的所有进程列表ProcessList:= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
2、提取进程列表项信息存储在TPROCESSENTRY32 pe中Process32First(ProcessList,pe)Process32Next(ProcessList,pe)
3、创建指定进程所有调用模块列表ModuleList:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,pe.processID);
4、提取调用模块列表项信息存储在TMODULEENTRY32 pm中Module32First(ModuleList,pm);Module32Next(ModuleList,pm);
三、核心源码
有了以上知识以后,我们就可以很容易地实现获取系统的所有进程以及各进程运行过程所调用的模块文件了。具体步骤如下:
1、运行Delphi,进入Delphi的IDE开发环境;2、新建Application;3、在默认的Form1中添加Treeview和Button控件;4、设置Button的OnClick属性为ProcessEnum;5、把以下代码输入ProcessEnum过程中;6、编译运行;
核心代码如下所示:uses Tlhelp32;procedure TForm1.ProcessEnum(Sender: TObject);varProcessList :Thandle;pe :TPROCESSENTRY32;node :TTreenode;processnumber :integer;procedure ModuleEnum(processid:Dword);varModuleList :Thandle;pm :TMODULEENTRY32;beginModuleList:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,processID);pm.dwSize:=sizeof(TMODULEENTRY32);if module32first(ModuleList,pm)then begintreeview1.Items.addchild(node,pm.szexepath);while module32next(ModuleList,pm) dotreeview1.items.addchild(node,pm.szexepath);end;closehandle(ModuleList);end; // ModuleEnum begin // ProcessEnumprocessnumber:=0;treeview1.Items.Clear;ProcessList:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);pe.dwSize:=sizeof(TPROCESSENTRY32);if process32first(ProcessList,pe) thenbeginnode:=treeview1.Items.Add(nil,pe.szexefile);ModuleEnum(pe.th32ProcessID);inc(processnumber);while process32next(ProcessList,pe) dobeginnode:=treeview1.Items.Add(nil,pe.szexefile);ModuleEnum(pe.th32ProcessID);inc(processnumber);end;end;edit1.text:='系统进程:'+inttostr(processnumber);closehandle(ProcessList);end;
var lppe: TProcessEntry32;
found : boolean;
Hand : THandle;
begin
Hand := CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
found := Process32First(Hand,lppe);
while found do
begin
ListBox.Items.Add(StrPas(lppe.szExeFile));//列出所有进程。
found := Process32Next(Hand,lppe);
end;
end;/////////////////////////////////////////////////////
uses ... TLHelp32, ...type
TForm1 = class(TForm)
...
end;var
Form1: TForm1;
l : Tlist; ////返回的东东在"L"这个TList中。type
TProcessInfo = Record
ExeFile : String;
ProcessID : DWORD;
end;
pProcessInfo = ^TProcessInfo;implementation{$R *.DFM}procedure TForm1.FormCreate(Sender: TObject);
var p : pProcessInfo;
i : integer;
ContinueLoop:BOOL;
var
FSnapshotHandle:THandle;
FProcessEntry32:TProcessEntry32;
begin
l := TList.Create;
l.Clear;
FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
FProcessEntry32.dwSize:=Sizeof(FProcessEntry32);
ContinueLoop:=Process32First(FSnapshotHandle,FProcessEntry32);
while integer(ContinueLoop)<>0 do
begin
New(p);
p.ExeFile := FProcessEntry32.szExeFile;
p.ProcessID := FProcessEntry32.th32ProcessID;
l.Add(p);
ContinueLoop:=Process32Next(FSnapshotHandle,FProcessEntry32);
end;
end;procedure TForm1.FormDestroy(Sender: TObject);
var p : pProcessInfo;
i : integer;
begin
With l do
for i := Count - 1 DownTo 0 do
begin p := items[i]; Dispose(p); Delete(i); end;
end;...
end.
///////////////////////////////////
procedure TForm1.Button1Click(Sender: TObject);
{Places the modulenames of the running/minimized tasks into a listbox }
var
pTask : pTaskEntry; {requires Uses ToolHelp}
Task : bool;
Pstr : array [0..79] of Char;
Str : string[80];
byt_j : byte;
begin
ListBox1.Clear;
GetMem(pTask, SizeOf(TTaskEntry)); {Reserve memory for TaskEntry}
pTask^.dwSize:=SizeOf(TTaskEntry);
byt_j:=0; {Set up a counter for number of tasks}
Task:=TaskFirst(pTask); {Find first task}
While task do
begin
inc(byt_j); {count number of different tasks}
Str:=StrPas(pTask^.szModule); {Convert PStr into Pascal string}
Listbox1.Items.Add(str); {Store Pascal string into listbox}
task:=taskNext(pTask); {Check for next possible task}
end;
Label1.Caption:=IntToStr(byt_j)+ ' tasks found'; {Show counter}
end;
var
i:integer;
strList:TStringList;
StrAppName:String;
blApp:integer;
{-----------------}
hand:thandle;
lppe:PROCESSENTRY32;
found,bOver:boolean;
begin
strList:=TStringList.Create;
MyIniFile:=TIniFile.Create(FilePath);
MyIniFile.ReadSectionValues('AppName',strList);
blApp:=0;
if myGetVersion<>'Windows 95' then begin
for i:=0 to strList.Count -1 do begin
Hand:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
StrAppName:=Copy(StrList[i],Pos('=',StrList[i])+1,Length(StrList[i]));
if hand>0 then
lppe.dwSize:= sizeof(PROCESSENTRY32);
found:=Process32First(Hand,lppe);
while found do begin
if strpas(lppe.szExeFile)=StrAppName then begin
blApp:=blApp+1;
end;
found:=Process32next(Hand,lppe);
end;
closehandle(hand);
end; for i:=0 to StrList.Count -1 do begin
if blApp<>strList.Count then begin
result:=false;
exit;
end
end;
result:=true;
end
else begin
//frmMain.N12.Visible:=false;
//frmMain.N11.Visible:=false;
bOver:=false;
StrAppName:=MyiniFile.ReadString('AppName','被控程序[0]','');
showmessage(strAppName);
Hand := CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
found := Process32First(Hand,lppe);
while found do begin
showmessage(strpas(lppe.szExeFile));
if Pos(pchar(StrAppName),pchar(StrPas(lppe.szExeFile)))<>0 then begin
bOver:=true;
break;
end;
found := Process32Next(Hand,lppe);
end;
closehandle(hand);
result:=bOver;
end;end;
--------------------
我想实现从ini文件中提取程序名,然后遍历整个进程表,看该程序是否在运行..
如果在运行的话,就返回true,否则false程序在编译时没有任何错误,生成exe后,在98下运行就内存地址错误啊~~~急..另开一贴~~~