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

VC++ 實現枚舉系統進程的四種核心方法詳解

     編輯:VC 教學

前言

在 Windows 2000 及以上作業系統中,透過工作管理器或 Windows XP 的 Tasklist 命令,我們可以輕鬆查看所有正在執行的進程。但這些工具背後的實現原理是什麼?秉持著侯捷大師在《深入淺出 MFC》中提倡的「知其然更要知其所以然」精神,本文將帶您親手實作四種枚舉系統進程的經典方案,所有程式碼均在 Windows XP SP1 + VC6.0 SP6 環境下編譯通過。

方法一:ToolHelp32 API —— 最經典的快照遍歷法

這是最廣為人知的方法,核心在於三個 API 函數:CreateToolhelp32Snapshot()、Process32First() 與 Process32Next()。

核心函數原型

HANDLE WINAPI CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID);
BOOL WINAPI Process32First(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);
BOOL WINAPI Process32Next(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);

實作邏輯

  1. 呼叫 CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) 建立系統進程快照句柄。
  2. 使用 Process32First() 取得第一筆進程資訊。
  3. 在 while 迴圈中反覆呼叫 Process32Next() 遍歷所有進程,並可輔以 CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ...) 取得模組完整路徑。

筆者曾反編譯 Sysinternals 的 Pslist.exe,發現其核心邏輯正是基於此法。MSDN 亦提供功能更完善的範例程式碼供參考。

方法二:PSAPI 動態載入法 —— 突破 SDK 缺失的靈活方案

雖然 MSDN 提供了 EnumProcesses 與 EnumProcessModules 的範例,但 VC6.0 自帶 SDK 卻缺少 psapi.h 與對應的導入庫。解決之道在於動態載入 Psapi.dll 並手動獲取函數入口位址。

關鍵技術點

  • 使用 typedef 定義函數指標,並指定 _stdcall 呼叫慣例。
  • 透過 LoadLibrary 載入 Psapi.dll,再用 GetProcAddress 取得 EnumProcesses、EnumProcessModules、GetModuleFileNameEx 等函數位址。
  • 此法不依賴編譯期標頭檔,相容性極佳。

方法三:WMI (Windows Management Instrumentation) —— 企業級管理的標準之選

WMI 提供了統一的系統管理介面,透過 IWbemLocator、IWbemServices 等 COM 介面,可查詢 Win32_Process 類別,獲得豐富的進程屬性(命令列、啟動時間、擁有者等)。雖然程式碼較繁瑣,但功能最強大,適合管理工具開發。

方法四:NtQuerySystemInformation —— 核心層級的高效能方案

直接呼叫未文件化的 NtQuerySystemInformation(SystemProcessInformation, ...) 可一次性取得所有進程資訊,效能最高,但屬非公開 API,版本相容性風險較大,建議僅用於特殊需求場景。

總結與建議

方法優點缺點適用場景
ToolHelp32API 穩定、文件完整、易上手需建立快照,效能稍遜一般應用程式、診斷工具
PSAPI 動態載入不依賴 SDK 版本、可獲取模組詳細資訊程式碼較繁瑣需相容舊版 VC 環境的專案
WMI資訊最豐富、支援遠端查詢啟動較慢、COM 程式碼複雜企業級管理代理、資產掃描
NtQuerySystemInformation效能極佳、一次取得所有資料非公開 API、有相容風險高頻輪詢、核心模組開發

實務上建議優先使用 ToolHelp32 或 PSAPI;若需豐富中繼資料則選 WMI;極致效能場景才考慮 Native API。掌握多種手法,才能在不同專案約束下游刃有餘。

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