每個執行中的應用程式都會在系統中形成一個進程。雖然多數程式提供視覺介面供使用者關閉,但無介面的背景程式(服務、監控工具等)只能透過工作管理員(Ctrl+Alt+Del)終止。系統監控類軟體若要實現進程列舉與管理,核心在於兩步:取得系統快照枚舉進程、依進程 ID 開啟並控制目標進程。
HANDLE WINAPI CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID);
dwFlags:指定快照類型,枚舉進程用 TH32CS_SNAPPROCESSth32ProcessID:指定進程 ID,0 表當前進程CloseHandle 釋放BOOL WINAPI Process32First(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);
BOOL WINAPI Process32Next(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);
配合 PROCESSENTRY32 結構取得完整進程資訊:
typedef struct tagPROCESSENTRY32 {
DWORD dwSize; // 結構大小(使用前必須設定)
DWORD cntUsage;
DWORD th32ProcessID; // 進程 ID(關鍵)
DWORD th32DefaultHeapID;
DWORD th32ModuleID;
DWORD cntThreads; // 執行緒數
DWORD th32ParentProcessID; // 父進程 ID
LONG pcPriClassBase; // 優先權基準
DWORD dwFlags;
CHAR szExeFile[MAX_PATH]; // 完整執行檔名稱
} PROCESSENTRY32;
PROCESSENTRY32 pe = {0};
pe.dwSize = sizeof(PROCESSENTRY32); // 必須初始化 dwSize
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) return;
if (Process32First(hSnapshot, &pe)) {
do {
int idx = m_listCtrl.AddString(pe.szExeFile);
m_listCtrl.SetItemData(idx, pe.th32ProcessID); // 存儲 PID 供後續終止使用
} while (Process32Next(hSnapshot, &pe));
}
CloseHandle(hSnapshot);
HANDLE OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);
dwDesiredAccess:存取權限,終止進程需 PROCESS_TERMINATEbInheritHandle:通常設 FALSEdwProcessId:目標進程 IDBOOL TerminateProcess(HANDLE hProcess, UINT uExitCode);
int idx = m_listCtrl.GetCurSel();
if (idx != LB_ERR) {
DWORD pid = m_listCtrl.GetItemData(idx);
HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
if (hProc) {
TerminateProcess(hProc, 0);
CloseHandle(hProc);
}
}
同樣 API 支援 TH32CS_SNAPTHREAD、TH32CS_SNAPMODULE、TH32CS_SNAPHEAP 等旗標,開發者可輕鬆擴充至執行緒枚舉、模組掃描、記憶體分析等進階功能。
<tlhelp32.h>、連結 kernel32.libPROCESSENTRY32.dwSize 未初始化會導致 API 失敗