Win32 進程管理核心 API:CreateProcess 精確控制啟動參數、TerminateProcess 強制結束、ShellExecute 簡易啟動文件/URL。本文完整實作與關鍵結構解析。
STARTUPINFO si = {0};
si.cb = sizeof(STARTUPINFO); // 必須設定
PROCESS_INFORMATION pi = {0}; // 接收輸出:hProcess, hThread, dwProcessId, dwThreadId
BOOL success = CreateProcess(
L"C:\\Windows\\System32\\calc.exe", // 應用程式路徑 (NULL 時從命令列解析)
NULL, // 命令列字串 (可覆蓋第一參數)
NULL, NULL, // 進程/執行緒安全屬性
FALSE, // 不繼承控制代碼
0, // 建立旗標 (CREATE_SUSPENDED 等)
NULL, // 環境區塊 (NULL 繼承父進程)
NULL, // 當前目錄 (NULL 繼承父進程)
&si, // STARTUPINFO
&pi // PROCESS_INFORMATION (輸出)
);
| 參數 | 說明 |
|---|---|
lpApplicationName | 完整路徑或 NULL。NULL 時從 lpCommandLine 解析第一個 token |
lpCommandLine | 完整命令列,**可修改緩衝區**,不可傳字串常值 |
bInheritHandles | TRUE:子進程繼承父進程可繼承的控制代碼 |
dwCreationFlags | CREATE_SUSPENDED、CREATE_NEW_CONSOLE、DETACHED_PROCESS 等 |
lpEnvironment | 環境變數區塊 (雙重 NULL 結尾),NULL 繼承 |
lpCurrentDirectory | 工作目錄,NULL 繼承 |
DWORD exitCode = 0;
GetExitCodeProcess(pi.hProcess, &exitCode); // STILL_ACTIVE (259) 表示仍在執行
TerminateProcess(pi.hProcess, exitCode); // 強制結束,不執行 DLL_PROCESS_DETACH
// 必須關閉控制代碼
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
#include <shellapi.h>
// ...
ShellExecute(
NULL, // hwnd (父視窗,NULL 為無)
NULL, // lpOperation (NULL 為 "open")
L"C:\\Windows\\System32\\notepad.exe", // lpFile
NULL, // lpParameters
NULL, // lpDirectory
SW_SHOWNORMAL // nShowCmd
);
| 特性 | CreateProcess | ShellExecute |
|---|---|---|
| 控制精度 | 完整 (環境、繼承、暫停、優先級) | 基本 (僅顯示模式) |
| 返回資訊 | PROCESS_INFORMATION (PID、控制代碼) | HINSTANCE (≤32 為錯誤代碼) |
| 文件關聯 | 不支援 (需自行解析) | **支援** (啟動 .txt、.html、URL 等) |
| UAC 提權 | 需 runas 動詞 + manifest | 直接 lpOperation = L"runas" |
| 適用場景 | 子進程管控、參數精確傳遞 | 啟動文件、URL、列印、編輯 |


SHELLEXECUTEINFO sei = {0};
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
sei.lpVerb = L"open";
sei.lpFile = L"notepad.exe";
sei.nShow = SW_SHOWNORMAL;
ShellExecuteEx(&sei);
// sei.hProcess 可取得進程控制代碼 (需 SEE_MASK_NOCLOSEPROCESS)
CreateProcess 傳入字串常值給 lpCommandLine → 寫入違規 (系統會修改緩衝區)si.cb = sizeof(STARTUPINFO) → 未定義行為TerminateProcess 濫用 → 資料遺失、DLL 未正確卸載、鎖定未釋放CloseHandle → 核心物件洩漏、PID 無法重用ShellExecute 返回值 ≤ 32 為錯誤,**不是**控制代碼,不可 CloseHandle