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

VC++ 啟動外部程式三大 API 深度解析

     編輯:VC 教學

應用程式常需啟動其他執行檔(如開啟記事本、瀏覽器、列印文件),Win32 提供 WinExec、ShellExecute、CreateProcess 三種主要 API,功能由簡到繁,適用場景各異。本文深度比較三者差異、參數細節與實戰範例。

一、WinExec:最簡單但受限

UINT WinExec(LPCSTR lpCmdLine, UINT uCmdShow);
  • 優點:參數極少,一行程式碼即可啟動。
  • 缺點:
    1. 16 位元遺留 API,僅為相容保留。
    2. 命令列參數以空格分隔,路徑含空格(如 Program Files)會失敗。
    3. 無法取得進程句柄、ID,無法等待結束、控制優先權、重導向 I/O。
// 範例:啟動記事本開啟檔案
WinExec("notepad.exe C:\\Logs\\app.log", SW_SHOW);

二、ShellExecute:文件關聯與多功能首選

HINSTANCE ShellExecute(
    HWND hwnd,           // 父視窗句柄
    LPCTSTR lpOperation, // "open", "print", "explore", "edit"...
    LPCTSTR lpFile,      // 檔案/執行檔/URL
    LPCTSTR lpParameters,// 傳遞參數
    LPCTSTR lpDirectory, // 工作目錄
    INT nShowCmd         // 顯示模式
);
  • 核心優勢:支援文件關聯——傳入 .txt、.pdf、mailto:、https:// 即自動啟動對應程式。
  • 回傳值:>32 代表成功,否則為錯誤碼(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);

三、CreateProcess:完全控制的專業選擇

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 / CreateProcessWinExec 會解析失敗
需取得進程/執行緒句柄、IDCreateProcess唯一提供 PROCESS_INFORMATION
需等待結束、取得退出碼CreateProcess + WaitForSingleObject完整同步控制
需重導向 stdin/stdout/stderrCreateProcess配合管道與 STARTUPINFO.hStd*
需指定使用者權限、桌面、環境變數CreateProcess / CreateProcessAsUser完整安全性控制

五、常見錯誤與除錯

  • 路徑未轉義:C:\Program Files\App.exe → C:\\Program Files\\App.exe 或 C:/Program Files/App.exe。
  • 工作目錄錯誤:子程式相對路徑載入 DLL/設定檔失敗 → 正確設定 lpCurrentDirectory。
  • Unicode/ANSI 不匹配:專案為 Unicode 卻傳 char* → 統一使用 TCHAR/_T()。
  • ShellExecute 回傳值誤判:HINSTANCE 轉 int 比較 > 32,不可直接當 BOOL 判斷。

掌握三者差異,依專案需求選擇最適 API,才能寫出穩健、可維護的啟動邏輯。

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