create toolhelp 32快照枚举过程
create toolhelp 32快照枚举过程
当每个APP应用实例运行时,将在当前系统下生成进程。 大多数APP应用程序都有一个可视界面,您可以使用标题栏上的关闭按钮关闭程序。 但是,许多在后台运行的程序都没有可视界面。 在这种APP应用程序中,只能通过CTRL ALT DEL热键调用“关闭程序”对话框来查看当前系统进程的列表并完成指定的任务。 显然,这一功能在某些系统监控类软件中仍然非常需要,其处理过程大致可以分为两个阶段。 利用系统快照实现系统当前进程的枚举,并根据枚举结果管理进程。 介绍这个过程的实现。
枚举当前进程
要枚举当前系统中打开的所有进程,必须首先获取加载到内存中的进程的当前状态信息。 在Windows操作系统中,这些进程的当前状态信息不能直接从进程本身获取。 系统可以生成系统快照,该快照是存储在系统内存中的所有进程、线程、模块等当前状态信息的只读副本,用户可以通过访问系统快照来检测进程的当前状态在具体实现中,系统快照句柄的获取通过Win32 API函数CreateToolhelp32Snapshot ()进行,不仅是进程快照,还有堆、模块、线程的系统快照
在使用此函数之前,头文件必须包含tlhelp32.h头文件。
CreateToolhelp32Snapshot函数创建指定进程、进程使用的堆[HEAP]、模块[MODULE]和线程[THREAD]的快照[snapshot]
handlewinapicreatetoolhelp 32 snapshot (
DWORD dwFlags,
dword th32进程
);
参数:其中参数dwFlags:指定要创建包含何种类型的系统信息的快照句柄。 由于本程序只获取系统进程信息,所以TH32CS_SNAPPROCESS; 函数的第二个参数th32ProcessID `指定进程的标识号,如果设置为0,则指定当前进程。
dwFlags
指定要包含在“输入”快照中的系统内容。 此参数可以是以下数值(变量)之一:
TH32CS_INHERIT -声明快照句柄是可继承的。
th32cs_snapall-包括快照中的系统中的所有进程和线程。
在快照中包括由th32 cs _ snapheaplist-th32 processid指定的进程的所有堆。
在快照中包括由th32 cs _ snap module-th32 processid指定的进程的所有模块。
TH32CS_SNAPPROCESS -将系统中的所有进程包括在快照中。
TH32CS_SNAPTHREAD -在快照中包括系统中的所有线程。
th32ProcessID
[输入]指定要快照的进程ID。 如果参数为0,则表示快照的当前进程。 此参数仅在设置了TH32CS_SNAPHEAPLIST或TH32CS_SNAPMOUDLE时有效,否则将被忽略,并且所有进程都将被快照。
返回值:
调用成功,返回快照句柄,调用失败,返回INVAID_HANDLE_VALUE。
注释:
使用GetLastError函数查找函数生成的错误状态代码。
要删除快照,请使用CloseHandle函数。
获取快照句柄后,只能以只读方式进行访问。 使用系统快照句柄与使用普通对象句柄没有太大区别,使用后必须使用CloseHandle ()函数将其丢弃。
BOOL Process32First ()函数
参数:从HANDLE hSnapshot传递的Snapshot句柄
参数:指向LPPROCESSENTRY32 lppe的PROCESSENTRY32结构的指针
角色—从快照中获取初始进程日志信息
BOOL Process32Next ()函数
参数:从HANDLE hSnapshot传递的Snapshot句柄
参数:指向LPPROCESSENTRY32 lppe的PROCESSENTRY32结构的指针
角色:从快照中获取以下进程记录信息
BOOL Module32First ()函数
参数:从HANDLE hSnapshot传递的Snapshot句柄
参数: LPMODULEENTRY3 lpme是指向MODULEENTRY32结构的指针
角色:从Snapshot获得第一个模型记录信息
BOOL Module32Next ()函数
参数:从HANDLE hSnapshot传递的Snapshot句柄
参数: LPMODULEENTRY3 lpme是指向MODULEENTRY32结构的指针
作用:从Sn
apshot得到下一个Module记录信息BOOL Thread32First()函数
参数:HANDLE hSnapshot传入的Snapshot句柄
参数:LPTHREADENTRY32 lpte指向一个 THREADENTRY32结构的指针
作用:从Snapshot得到第一个Thread记录信息
BOOL Thread32Next()函数
参数:HANDLE hSnapshot传入的Snapshot句柄
参数:LPTHREADENTRY32 lpte指向一个 THREADENTRY32结构的指针
作用:从Snapshot得到下一个Thread记录信息
HANDLE OpenProcess()函数
参数:DWORD dwDesiredAccess 权限描叙信息
这里我用到了PROCESS_ALL_ACCESS功能是具有所有权限
参数:BOOL bInheritHandle 确定该句柄是否可以被程继承
参数:dwPrcessID 进程ID号
作用:打开一个存在的进程对象
列举进程
在得到系统的快照句柄后,就可以对当前进程的标识号进行枚举了,通过这些枚举出的进程标识号可以很方便的对进程进行管理。进程标识号通过函数Process32First() 和 Process32Next()而得到,这两个函数可以枚举出系统当前所有开启的进程,并且可以得到相关的进程信息。 这两个函数原型声明如下:
BOOL WINAPI Process32First(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);
BOOL WINAPI Process32Next(HANDLE hSnapshot,LPPROCESSENTRY32 lppe);
以上两个函数分别用于获得系统快照中第一个和下一个进程的信息,并将获取得到的信息保存在指针lppe所指向的PROCESSENTRY32结构中。函数第一个参数hSnapshot为由CreateToolhelp32Snapshot()函数返回得到的系统快照句柄;第二个参数lppe为指向结构PROCESSENTRY32的指针,PROCESSENTRY32结构可对进程作一个较为全面的描述,其定义如下:
typedef struct tagPROCESSENTRY32 {
DWORD dwSize; // 结构大小;
DWORD cntUsage; // 此进程的引用计数;
DWORD th32ProcessID; // 进程ID;
DWORD th32DefaultHeapID; // 进程默认堆ID;
DWORD th32ModuleID; // 进程模块ID;
DWORD cntThreads; // 此进程开启的线程计数;
DWORD th32ParentProcessID; // 父进程ID;
LONG pcPriClassBase; // 线程优先权;
DWORD dwFlags; // 保留;
char szExeFile[MAX_PATH]; // 进程全名;
} PROCESSENTRY32;
以上三个API函数均在头文件tlhelp32.h中声明,运行时需要有kernel32.lib库的支持。通过这三个函数可以枚举出当前系统已开启的所有进程,并可获取到进程的各相关信息。
例子:
#i nclude <windows.h>
#i nclude <tlhelp32.h>
#i nclude <iostream>
int main( )
{
// 现在我们将利用函数CreateToolhelp32Snapshot()获得当前运行进程的快照
//这个函数返回包含正在运行进程的快照句柄。
//他的原形是:
// HANDLE WINAPI CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID);
// 我们将dwFlags设为TH32CS_SNAPPROCESS,th32ProcessID置为0。
HANDLE hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
//现在我们获得了所有进程的信息。
//将从hSnapShot中抽取数据到一个PROCESSENTRY32结构中
//这个结构代表了一个进程,是ToolHelp32 API的一部分。
//抽取数据靠Process32First()和Process32Next()这两个函数。
//这里我们仅用Process32Next(),他的原形是:
//BOOL WINAPI Process32Next(HANDLE hSnapshot,LPPROCESSENTRY32 lppe);
//我们程序的代码中加入:
PROCESSENTRY32* processInfo=new PROCESSENTRY32;
// 必须设置PROCESSENTRY32的dwSize成员的值 ;
processInfo->dwSize=sizeof(PROCESSENTRY32);
int index=0;
//这里我们将快照句柄和PROCESSENTRY32结构传给Process32Next()。
//执行之后,PROCESSENTRY32 结构将获得进程的信息。我们循环遍历,直到函数返回FALSE。
printf("****************开始列举进程****************/n");
while(Process32Next(hSnapShot,processInfo)!=FALSE)
{
index++;
printf("****************** %d ******************/n",index);
printf("PID Name Current Threads/n");
printf("%-15d%-25s%-4d/n",processInfo->th32ProcessID,processInfo->szExeFile,processInfo->cntThreads);
}
CloseHandle(hSnapShot);
printf("****************进程列举结束****************/n");
int processID;
HANDLE hProcess;
printf("Enter Process ID to terminate that process:");
scanf("%d",&processID);
// 现在我们用函数 TerminateProcess()终止进程:
// 这里我们用PROCESS_ALL_ACCESS
hProcess=OpenProcess(PROCESS_ALL_ACCESS,TRUE,processID);
if(hProcess==NULL)
{
printf("Unable to get handle of process: ");
printf("Error is: %d",GetLastError());
}
TerminateProcess(hProcess,0);
delete processInfo;
return 0;
}