首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Windows C 語言獲取進程資訊完整實現:PID、優先級、親和性、命令列與啟動參數

     編輯:關於C語言

在 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 版本不匹配問題。

三、核心功能:`GetProcessInfo`


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; // 成功
}

四、命令列參數解析:`CommandLineToArgvW`

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 說明表

API用途注意事項
GetCurrentProcessId獲取 PID輕量,無失敗
GetCurrentProcess獲取偽句柄不可 CloseHandle,不可跨進程使用
GetPriorityClass優先級類別需有效進程句柄 (如 hInstance 對應進程)
GetProcessAffinityMaskCPU 親和性返回位遮罩,第 n 位對應第 n 個邏輯處理器
GetProcessWorkingSetSize工作集範圍反映物理記憶體佔用上下限
GetCommandLineW完整命令列包含程式名與所有參數,Unicode
CommandLineToArgvW解析參數陣列正確處理引號、轉義;返回陣列需 LocalFree
GetStartupInfo啟動參數填充 STARTUPINFO (wShowWindow, hStdInput...)

六、編譯與鏈接設定

  • 頭文件:``、``、``
  • 字符集:專案屬性 → 字符集 → 使用 Unicode 字符集 (關鍵,`GetCommandLineW` 等需 Unicode)。
  • 入口點:`WinMain` (GUI) 或 `wmain` (控制台 Unicode)。
  • 鏈接庫:`Kernel32.lib` (隱式鏈接)。

七、擴展方向

  1. 遠程進程:用 `OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid)` 獲取句柄,替換 `GetCurrentProcess()`/`hMySelf`。
  2. 句柄計數:需 `NtQueryInformationProcess` (ntdll.dll) 或 `GetProcessHandleCount` (Vista+)。
  3. 模組枚舉:`EnumProcessModulesEx` 獲取載入 DLL 列表。
  4. 效能計數器:PDH API 獲取 CPU/記憶體/IO 即時數據。

此實現為 Windows 進程自省提供了堅實基礎,掌握這些 API 組合是開發任務管理器、偵錯器、效能分析器的核心技能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved