在 Windows 系統程式開發中,獲取當前或目標進程的詳細資訊是診斷、監控與安全工具的基礎。本文提供一個完整的 C 語言實現,使用 WinAPI 獲取進程 ID、句柄、優先級類別、句柄數、CPU 親和性遮罩、工作集大小、命令列參數與啟動資訊,代碼結構清晰,可直接整合至專案。
typedef struct _PROCESS_INFO {
DWORD dwPid; // 進程 ID
HANDLE hProcess; // 進程句柄
DWORD dwPrioClass; // 優先級類別
DWORD dwHandleCount; // 句柄數 (此處未填充,需 NtQueryInformationProcess)
DWORD dwAffinityMask; // CPU 親和性遮罩
SIZE_T dwWorkingSetSizeMax; // 最大工作集
SIZE_T dwWorkingSetSizeMin; // 最小工作集
LPWSTR szwCommandLine; // 完整命令列 (Unicode)
STARTUPINFO sit; // 啟動資訊結構
} PROCESS_INFO, *LPPROCESS_INFO;
#define MyAlloc(size) HeapAlloc(GetProcessHeap(), 0, size)
#define MyFree(ptr) HeapFree(GetProcessHeap(), 0, ptr)
使用進程預設堆,避免 `malloc`/`free` 與 CRT 版本不匹配問題。
DWORD GetProcessInfo(LPPROCESS_INFO lppi) {
// 1. 基本標識
lppi->dwPid = GetCurrentProcessId();
lppi->hProcess = GetCurrentProcess(); // 偽句柄,無需 CloseHandle
// 2. 優先級類別
lppi->dwPrioClass = GetPriorityClass(hMySelf); // 需全域/傳入 hInstance
// 3. CPU 親和性
GetProcessAffinityMask(hMySelf, &lppi->dwAffinityMask, NULL);
// 4. 工作集大小 (物理記憶體使用範圍)
GetProcessWorkingSetSize(hMySelf,
&lppi->dwWorkingSetSizeMin,
&lppi->dwWorkingSetSizeMax);
// 5. 完整 Unicode 命令列
lppi->szwCommandLine = GetCommandLineW(); // 指向進程環境塊,無需釋放
// 6. 啟動資訊 (視窗顯示狀態、標準句柄等)
GetStartupInfo(&lppi->sit);
return 0; // 成功
}
WinMain 參數 `lpCmdLine` 已去除程式名,且為 ANSI。若需完整 Unicode 參數陣列:
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
PROCESS_INFO pi;
GetProcessInfo(&pi);
INT argc;
LPWSTR *argv = CommandLineToArgvW(pi.szwCommandLine, &argc);
// argv[0] 為完整路徑, argv[1..argc-1] 為參數
// 轉換為 ANSI 顯示 (MessageBoxA 需 ANSI)
for (int i = 0; i < argc; i++) {
int len = lstrlenW(argv[i]) + 1;
LPSTR ansi = MyAlloc(len);
WideCharToMultiByte(CP_ACP, 0, argv[i], -1, ansi, len, NULL, NULL);
// 累加到顯示緩衝區...
MyFree(ansi);
}
LocalFree(argv); // 必須釋放 argv 陣列本身
// ...
}
| API | 用途 | 注意事項 |
|---|---|---|
| GetCurrentProcessId | 獲取 PID | 輕量,無失敗 |
| GetCurrentProcess | 獲取偽句柄 | 不可 CloseHandle,不可跨進程使用 |
| GetPriorityClass | 優先級類別 | 需有效進程句柄 (如 hInstance 對應進程) |
| GetProcessAffinityMask | CPU 親和性 | 返回位遮罩,第 n 位對應第 n 個邏輯處理器 |
| GetProcessWorkingSetSize | 工作集範圍 | 反映物理記憶體佔用上下限 |
| GetCommandLineW | 完整命令列 | 包含程式名與所有參數,Unicode |
| CommandLineToArgvW | 解析參數陣列 | 正確處理引號、轉義;返回陣列需 LocalFree |
| GetStartupInfo | 啟動參數 | 填充 STARTUPINFO (wShowWindow, hStdInput...) |
此實現為 Windows 進程自省提供了堅實基礎,掌握這些 API 組合是開發任務管理器、偵錯器、效能分析器的核心技能。