CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) 取得系統進程快照,配合 Process32First/Next 遍歷 PROCESSENTRY32 結構。優點:支援 Win9x~Win11、無需 WMI/PDH 額外相依、速度快。
#include
#include // ToolHelp32 API
#pragma hdrstop
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
void __fastcall TForm1::RefreshProcessList() {
ListView1->Items->Clear();
ListView1->Items->BeginUpdate();
try {
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap == INVALID_HANDLE_VALUE) {
ShowMessage("建立快照失敗: " + IntToStr(GetLastError()));
return;
}
PROCESSENTRY32 pe = { sizeof(PROCESSENTRY32) };
if (Process32First(hSnap, &pe)) {
do {
TListItem* item = ListView1->Items->Add();
item->Caption = pe.szExeFile; // 進程名稱
item->SubItems->Add(IntToStr(pe.th32ProcessID)); // PID
item->SubItems->Add(IntToStr(pe.th32ParentProcessID)); // 父 PID
item->SubItems->Add(IntToStr(pe.cntThreads)); // 執行緒數
item->SubItems->Add(IntToStr(pe.pcPriClassBase)); // 基礎優先權
// 取得檔案版本資訊 (選擇性)
AnsiString exePath = GetModuleFileNameExForPID(pe.th32ProcessID); // 需自行實作或用 PSAPI
if (!exePath.IsEmpty()) {
DWORD dwHandle, dwSize = GetFileVersionInfoSize(exePath.c_str(), &dwHandle);
if (dwSize) {
std::vector buf(dwSize);
if (GetFileVersionInfo(exePath.c_str(), 0, dwSize, buf.data())) {
UINT len; void* pVal;
// 語言/代碼頁通常為 040904B0 (英文美語) 或 080404B0 (中文繁體)
// 實務應先查詢 VarFileInfo\Translation 取得正確語言代碼
char subBlock[128];
wsprintf(subBlock, "\\StringFileInfo\\040904B0\\FileVersion");
if (VerQueryValue(buf.data(), subBlock, &pVal, &len))
item->SubItems->Add(AnsiString((char*)pVal));
wsprintf(subBlock, "\\StringFileInfo\\040904B0\\CompanyName");
if (VerQueryValue(buf.data(), subBlock, &pVal, &len))
item->SubItems->Add(AnsiString((char*)pVal));
wsprintf(subBlock, "\\StringFileInfo\\040904B0\\FileDescription");
if (VerQueryValue(buf.data(), subBlock, &pVal, &len))
item->SubItems->Add(AnsiString((char*)pVal));
}
}
}
} while (Process32Next(hSnap, &pe));
}
CloseHandle(hSnap);
} __finally {
ListView1->Items->EndUpdate();
}
}
#include
#pragma comment(lib, "psapi.lib")
AnsiString GetModuleFileNameExForPID(DWORD pid) {
HANDLE hProc = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ, FALSE, pid);
if (!hProc) return "";
char path[MAX_PATH * 2] = {0};
DWORD len = GetModuleFileNameEx(hProc, NULL, path, sizeof(path));
CloseHandle(hProc);
return (len > 0) ? AnsiString(path) : "";
}
void __fastcall TForm1::BtnTerminateClick(TObject *Sender) {
if (ListView1->Selected == NULL) {
ShowMessage("請先選擇要終止的進程");
return;
}
// 取得父進程 ID (欄位索引 2)
DWORD parentPID = StrToIntDef(ListView1->Selected->SubItems->Strings[1], 0);
if (parentPID == 0) {
ShowMessage("無效的父進程 ID");
return;
}
// 確認對話框
if (Application->MessageBox(
("確定要終止 PID " + IntToStr(parentPID) + " 及其子進程嗎?").c_str(),
"確認終止", MB_YESNO | MB_ICONWARNING) != IDYES)
return;
// 開啟進程需 TERMINATE 權限
HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, parentPID);
if (!hProc) {
ShowMessage("OpenProcess 失敗,錯誤碼: " + IntToStr(GetLastError()) +
" (可能權限不足,請以管理員身分執行)");
return;
}
if (TerminateProcess(hProc, -1)) {
ShowMessage("進程終止信號已發送 (退出碼 -1)");
} else {
ShowMessage("TerminateProcess 失敗,錯誤碼: " + IntToStr(GetLastError()));
}
CloseHandle(hProc);
// 重新整理列表
RefreshProcessList();
}
th32ParentProcessID,終止時使用該值。OpenProcess(PROCESS_TERMINATE) 需目標進程 DACL 允許。系統進程 (csrss.exe, services.exe, lsass.exe)、高完整性進程 (管理員執行) 預設拒絕一般使用者終止。requireAdministrator,或以「系統管理員身分執行」。SeDebugPrivilege (參考文章 7850 EnableDebugPriv)。VerQueryValue 的 \\StringFileInfo\\LangCodePage\\Key 中 LangCodePage 為 4 位元組語言 ID + 4 位元組代碼頁 (十六進位)。040904B0 (英文/1200), 080404B0 (中文繁體/1200), 040404E4 (中文簡體/936)。\\VarFileInfo\\Translation 取得陣列,逐一嘗試,而非硬編碼。OpenProcess + GetModuleFileNameEx 取得名稱,較慢但無 ToolHelp32 相依 (NT 4.0 SP4+ 內建)。SELECT ProcessId, Name, ExecutablePath, ParentProcessId, CommandLine FROM Win32_Process。功能最強 (可取得命令列參數)、跨機器查詢,但需 COM 初始化、速度較慢、依賴 WMI 服務。TListView 設定 ViewStyle = vsReport, ReadOnly = true, RowSelect = true, FullRowSelect = true。TTimer 間隔 3~5 秒自動 RefreshProcessList,或提供手動重新整理按鈕。MiniDumpWriteDump)。ToolHelp32 API 提供了輕量、高效、跨版本的進程列舉能力。結合 PSAPI 取得完整路徑與版本資訊,並針對父進程 ID 實施終止策略,即可構建實用的進程管理工具核心。務必嚴守權限最小化、操作可審計、關鍵進程受保護三大原則,確保工具在實際部署中安全可控。