在 Windows 下可以通过使用 PSAPI 库来创建进程列表,用以枚举正在运行的进程的信息。为了使用 PSAPI 库中的函数,需要在 Platform SDK 中找到 PSAPI.h 和 PSAPI.lib 两个文件, PSAPI.h 里声明了所需要的函数。
#include "PSAPI.h" #pragma comment(lib, "psapi.lib")
|
要创建进程列表首先要调用 EnumProcesses()函数。该函数的声明如下:
BOOL
WINAPI
EnumProcesses (
DWORD *lpidProcess,
DWORD cb,
DWORD *cbNeeded
);
|
其中,DWORD 类型的数组指针 lpidProcess;该数组的大小尺寸 cb;以及一个指向 DWORD 的指针 cbNeeded,它接收返回数据的长度。DWORD 数组用于保存当前运行的进程ID。cbNeeded 返回数组所用的内存大小。
然后通过
int nProcesses = cbNeeded / sizeof(DWORD);
|
可以得到进程的总数。
值得注意的是:虽然文档将返回的 DWORD 命名为“cbNeeded”,实际上是没有办法知道到底要传多大的数组的。EnumProcesses()根本不会在 cbNeeded 中返回一个大于 cb 参数传递的数组值。结果,唯一确保 EnumProcesses()函数成功的方法是分配一个 DWORD 数组,并且,如果返回的 cbNeeded 等于 cb,分配一个较大的数组,并不停地尝试直到cbNeeded 小于 cb 。
这样,就获得了一个数组,其元素保存着系统中每个进程的ID。
如果你要想获取进程的名字,那么必须首先获取一个句柄。从进程 ID 得到句柄,就得调用 OpenProcess()函数:
WINBASEAPI
HANDLE
WINAPI
OpenProcess(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwProcessId
);
|
其中 dwProcessId 就是刚刚得到的进程 ID。
得到了 HANDLE ,则需要得到该进程的第一个模块。为此调用 EnumProcessModules() API:
BOOL WINAPI EnumProcessModules( HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded );
|
调用之后,hModule 变量中保存的将是进程中的第一个模块。记住进程其实没有名字,但进程的第一个模块既是该进程的可执行模块。
现在你可以用 hModule 中返回的模块句柄调用 GetModuleBaseName() API 函数获取全路径名,或者是进程的可执行模块名:
DWORD GetModuleBaseName( HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName, DWORD nSize );
|
函数四个参数分别是:进程句柄,模块句柄,返回名字的缓冲指针以及缓冲大小尺寸。其中的lpBaseName就是模块名字了。
下面是一个我写的通过进程名得到进程ID的小例子,只需稍加改动就能得到其他的功能了。
DWORD getProcessByName(LPCTSTR name) { // LPCTSTR name = "foxmail.exe";
DWORD aProcesses[1024], cbNeeded, ModNeeded; if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) return -1;
// Calculate how many process identifiers were returned.
HANDLE hProcess; HMODULE hMod; char szProcessName[MAX_PATH] = "unknown"; int nProcesses = cbNeeded / sizeof(DWORD); for ( int i = 0; i < nProcesses; i++ ) { hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i] ); if (NULL != hProcess ) { if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &ModNeeded) ) { GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName) ); if (stricmp(szProcessName, name) == 0) { return aProcesses[i]; } } else continue; } } return -1; }
|
阅读(2141) | 评论(0) | 转发(0) |