應用程式常需啟動其他執行檔(如開啟記事本、瀏覽器、列印文件),Win32 提供 WinExec、ShellExecute、CreateProcess 三種主要 API,功能由簡到繁,適用場景各異。本文深度比較三者差異、參數細節與實戰範例。
UINT WinExec(LPCSTR lpCmdLine, UINT uCmdShow);
Program Files)會失敗。// 範例:啟動記事本開啟檔案
WinExec("notepad.exe C:\\Logs\\app.log", SW_SHOW);
HINSTANCE ShellExecute(
HWND hwnd, // 父視窗句柄
LPCTSTR lpOperation, // "open", "print", "explore", "edit"...
LPCTSTR lpFile, // 檔案/執行檔/URL
LPCTSTR lpParameters,// 傳遞參數
LPCTSTR lpDirectory, // 工作目錄
INT nShowCmd // 顯示模式
);
.txt、.pdf、mailto:、https:// 即自動啟動對應程式。SE_ERR_*)。// 開啟計算機
ShellExecute(m_hWnd, _T("open"), _T("calc.exe"), _T(""), _T(""), SW_SHOW);
// 以記事本開啟指定日誌
ShellExecute(m_hWnd, _T("open"), _T("notepad.exe"), _T("C:\\Logs\\app.log"), _T(""), SW_SHOW);
// 直接開啟文件(自動關聯)
ShellExecute(m_hWnd, _T("open"), _T("C:\\Docs\\report.pdf"), _T(""), _T(""), SW_SHOW);
// 發送 Email
ShellExecute(m_hWnd, _T("open"), _T("mailto:user@example.com"), _T(""), _T(""), SW_SHOW);
// 列印文件(背景列印)
ShellExecute(m_hWnd, _T("print"), _T("C:\\Docs\\doc.docx"), _T(""), _T(""), SW_HIDE);
子程式 call.exe 在 InitInstance 讀取 __argc/__targv:
ShellExecute(NULL, NULL, _T("C:\\Tools\\call.exe"), _T("arg1 arg2 arg3"), NULL, SW_SHOW);
BOOL CreateProcess(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
STARTUPINFO si = { sizeof(STARTUPINFO) };
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWMAXIMIZED; // 啟動時最大化
PROCESS_INFORMATION pi;
BOOL bOk = CreateProcess(
_T("C:\\Tools\\worker.exe"), // lpApplicationName
NULL, // lpCommandLine (NULL 時用第一參數)
NULL, NULL, // 安全性預設
FALSE, // 不繼承控制代碼
0, // 建立旗標
NULL, // 環境區塊預設
NULL, // 目前目錄預設
&si, &pi);
if (bOk) {
// 等待子程式結束,最多 10 秒
WaitForSingleObject(pi.hProcess, 10000);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
AfxMessageBox(_T("子程式已結束"));
}
| 需求 | 推薦 API | 理由 |
|---|---|---|
| 快速啟動 .exe,無參數、無控制需求 | WinExec / ShellExecute | 程式碼最少 |
| 開啟文件/URL/郵件(依關聯) | ShellExecute | 唯一支援文件關聯 |
| 路徑含空格、需傳複雜參數 | ShellExecute / CreateProcess | WinExec 會解析失敗 |
| 需取得進程/執行緒句柄、ID | CreateProcess | 唯一提供 PROCESS_INFORMATION |
| 需等待結束、取得退出碼 | CreateProcess + WaitForSingleObject | 完整同步控制 |
| 需重導向 stdin/stdout/stderr | CreateProcess | 配合管道與 STARTUPINFO.hStd* |
| 需指定使用者權限、桌面、環境變數 | CreateProcess / CreateProcessAsUser | 完整安全性控制 |
C:\Program Files\App.exe → C:\\Program Files\\App.exe 或 C:/Program Files/App.exe。lpCurrentDirectory。char* → 統一使用 TCHAR/_T()。HINSTANCE 轉 int 比較 > 32,不可直接當 BOOL 判斷。掌握三者差異,依專案需求選擇最適 API,才能寫出穩健、可維護的啟動邏輯。