引言
每一个应用程序实例在运行起来后都会在当前系统下产生一个进程,大多数应用程序均拥有可视界面,用户可以通过标题栏上的关闭按钮关闭程序。但是也有为数不少的在后台运行的程序是没有可视界面的,对于这类应用程序用户只能通过CTRL+ALT+DEL热键呼出"关闭
程序"对话框显示出当前系统进程列表,从中可以结束指定的任务。显然,该功能在一些系统监控类软件中还是非常必需的,其处理过程大致可以分为两步:借助系统快照实现对系统当前进程的枚举和根据枚举结果对进程进行管理。本文下面即将对此过程的实现进行介绍。
当前进程的枚举
要对当前系统所有已开启的进程进行枚举,就必须首先获得那些加载到内存的进程当前相关状态信息。在Windows操作系统下,这些进程的当前状态信息不能直接从进程本身获取,系统已为所有保存在系统内存中的进程、线程以及模块等的当前状态的信息制作了一个只读副本--系统快照,用户可以通过对系统快照的访问完成对进程当前状态的检测。在具体实现时,系统快照句柄的获取是通过Win32 API函数CreateToolhelp32Snapshot()来完成的,通过该函数不仅可以获取进程快照,而且对于堆、模块和线程的系统快照同样可以获取。该函数原型声明如下:
HANDLE WINAPI CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessID);
其中,参数dwFlags:指定将要创建包含哪一类系统信息的快照句柄,本
程序中只需要检索系统进程信息,因此可将其设置为TH32CS_SNAPPROCESS;函数第二个参数th32ProcessID`则指定了进程的标识号,当设置为0时指定当前进程。如果成功函数将返回一个包含进程信息的系统快照句柄。在得到快照句柄之后只能以只读的方式对其进行访问。至于对系统快照句柄的使用同普通对象句柄的使用并没有什么太大区别,在使用完之后也需要通过CloseHandle()函数将其销毁。
在得到系统的快照句柄后,就可以对当前进程的标识号进行枚举了,通过这些枚举出的进程标识号可以很方便的对进程进行管理。进程标识号通过函数 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库的支持。通过这三个函数可以枚举出当前系统已开启的所有进程,并可获取到进程的各相关信息,下面给出一个简单的应用示例。在此示例中将枚举出系统的所有进程,并获取各进程的标识号和相应程序的绝对路径,进程标识号在下一步对进程的管理中将要用到,
程序路径则直接通过列表控件显示出