VC/MFC 中啟動外部程式有四種主流 API,功能層層遞進。本文從參數複雜度、控制能力、適用場景四個維度深度對比,助你精準選型。
| API | 頭文件/庫 | 複雜度 | 控制能力 | 回傳值 | 適用場景 |
|---|---|---|---|---|---|
system() | <cstdlib> / 標準 C | 極簡 | 無 (同步阻塞) | int:-1錯誤/0無子進程/>0子進程ID | 簡單命令列、批次檔、無需互動 |
WinExec() | <windows.h> / Kernel32.lib | 簡單 | 僅顯示模式 | UINT:>31成功/0資源不足/錯誤碼 | 快速啟動 GUI 程式、無需進程控制 |
ShellExecute() | <shellapi.h> / Shell32.lib | 中等 | 操作動詞、顯示模式 | HINSTANCE:>32成功/錯誤碼 | 開啟文件/URL、列印、探索資料夾、關聯動作 |
CreateProcess() | <windows.h> / Kernel32.lib | 高 | 完全控制 (安全性、環境、IO重導向、優先權、除錯等) | BOOL:成功/失敗 (GetLastError) | 需精細控制子進程、服務、高安全性場景 |
system("D:\\game.exe");
system("mmc.exe \"c:\\windows\\system32\\gpedit.msc\""); // 含空格路徑需雙引號
// 缺點:閃現命令提示字元視窗、無法控制子進程、安全性風險 (命令注入)
WinExec("Notepad.exe", SW_SHOW);
WinExec("D:\\Program Files\\Test\\Test.exe", SW_SHOWMAXIMIZED);
// 路徑大小寫必須精確、無法獲取進程控制代碼、Microsoft 建議改用 CreateProcess
// 原型
HINSTANCE ShellExecute(
HWND hwnd, // 父視窗 (NULL=無)
LPCTSTR lpOperation, // 動詞: "open","edit","print","explore","find",NULL(預設open)
LPCTSTR lpFile, // 檔案/URL/可執行檔路徑
LPCTSTR lpParameters,// 參數 (僅 lpFile 為可執行檔有效)
LPCTSTR lpDirectory, // 預設工作目錄
INT nShowCmd // 顯示模式: SW_SHOW, SW_HIDE, SW_MAXIMIZE 等
);
// 範例
ShellExecute(NULL, _T("open"), _T("C:\\Test.txt"), NULL, NULL, SW_SHOWNORMAL); // 關聯開啟
ShellExecute(NULL, _T("print"), _T("C:\\Doc.docx"), NULL, NULL, SW_HIDE); // 列印
ShellExecute(hWnd, _T("explore"), _T("C:\\Windows"), NULL, NULL, SW_SHOW); // 開啟資料夾
ShellExecute(NULL, _T("open"), _T("https://www.example.com"), NULL, NULL, SW_SHOW); // 開啟網頁
優勢:自動處理檔案關聯、URL 協定、DDE 執行、顯示模式控制。
BOOL CreateProcess(
LPCTSTR lpApplicationName, // 模組名 (NULL 時從命令列解析)
LPTSTR lpCommandLine, // 完整命令列 (含參數)
LPSECURITY_ATTRIBUTES lpProcessAttr, // 進程安全屬性 (NULL=預設)
LPSECURITY_ATTRIBUTES lpThreadAttr, // 執行緒安全屬性
BOOL bInheritHandles, // 繼承控制代碼
DWORD dwCreationFlags, // 建立旗標 (CREATE_SUSPENDED, DETACHED_PROCESS, CREATE_NEW_CONSOLE 等)
LPVOID lpEnvironment, // 環境塊 (NULL=繼承父進程)
LPCTSTR lpCurrentDirectory, // 工作目錄
LPSTARTUPINFO lpStartupInfo, // 啟動資訊 (標準輸入/輸出/錯誤重導向、視窗屬性等)
LPPROCESS_INFORMATION lpProcInfo // 輸出: 進程/執行緒控制代碼與 ID
);
STARTUPINFO si = { sizeof(si) };
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.hStdInput = hChildStdinRead; // 重導向標準輸入
si.hStdOutput = hChildStdoutWrite; // 重導向標準輸出
si.hStdError = hChildStderrWrite; // 重導向標準錯誤
si.wShowWindow = SW_HIDE; // 隱藏視窗
CreateProcess 設定 STARTUPINFO 重導向 → 父進程讀寫管道實現雙向通訊CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS、無視窗、獨立控制台DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESSlpEnvironment 傳遞自訂環境變數、lpCurrentDirectory 指定工作目錄WinExec 相容舊碼)system 透過 cmd.exe 解析,極易命令注入,**嚴禁**未驗證使用者輸入傳入CreateProcess 直接建立進程,無 Shell 解析風險,參數分離傳遞最安全CreateProcess 用 lpApplicationName 分離模組名,或命令列雙引號包裹