PSAPI:
枚舉系統Process
PSAPI提供了一系列函數來查看系統中的各種資訊,包括Process,Modules,Device Driver等等,MSDN上介紹的很詳細。
今天就記錄一下使用PSAPI來枚舉系統中的所有Process。
主要使用的函數就這幾個:
EnumProcess(),OpenProcess(),CloseHandle(),GetModuleBaseName()和EnumProcessModules()。
1.使用EnumProcess()取得系統中的所有Process ID
如MSDN上所言,由於很難預測系統當前的Process個數,因此推薦使用一個較大的數組;
2.使用OpenProcess()取得Process Handle
需要對進程具有PROCESS_QUERY_INFORMATION和PROCESS_VM_READ許可權,對於有些系統進程可能會失敗,比如System Idle
Process
3.使用EnumProcessModules()取得可執行程式HMODULE控制代碼
取得Handle後,就可以使用EnumProcessModules()取得可執行程式HMODULE控制代碼了,這個函數可以返回Process載入的所有Module,這裡傳入大小為1的數組即可,它總是代表了可執行程式的控制代碼。
4.使用GetModuleBaseName()獲得Process名字
取得Process的可執行程式名字,不包含路徑;
5.CloseHandle()關閉進程控制代碼
這一步不要忘了。
最後貼下樣本程式碼:
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
#pragma comment(lib, "psapi.lib")
int main()
{
DWORD vecProcessID[2048]; // sufficient most of time
DWORD cbNeeded, dwSize;
dwSize = sizeof(vecProcessID);
// if cbNeeded
>= sizeof(vecProcessID) try again with a larger array
if(EnumProcesses(vecProcessID,
dwSize, &cbNeeded)){
HANDLE hProcess;
HMODULE hMod; //
we only need the first module handle here
dwSize = cbNeeded/sizeof(vecProcessID[0]);
for(DWORD
i = 0; i < dwSize; i++){
char
name[MAX_PATH] = "<Unknown>";
hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,
FALSE, vecProcessID[i]);
if(hProcess
!= NULL){
if(EnumProcessModules(hProcess,
&hMod, sizeof(hMod),
&cbNeeded)){
GetModuleBaseName(hProcess,
hMod, name, sizeof(name)-1);
}
else{
printf("EnumProcessModules[%u] Error:%u/n",
vecProcessID[i], GetLastError());
}
CloseHandle(hProcess);
}
printf("%u/t%s/n",
vecProcessID[i], name);
}
}
return 0;
}