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

VC 調用外部程式四大 API 深度對比與選型指南

     編輯:關於VC++

VC/MFC 中啟動外部程式有四種主流 API,功能層層遞進。本文從參數複雜度、控制能力、適用場景四個維度深度對比,助你精準選型。

四大 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)需精細控制子進程、服務、高安全性場景

詳細用法與範例

1. system() - 最簡單但受限

system("D:\\game.exe");
system("mmc.exe \"c:\\windows\\system32\\gpedit.msc\"");  // 含空格路徑需雙引號
// 缺點:閃現命令提示字元視窗、無法控制子進程、安全性風險 (命令注入)

2. WinExec() - 16 位遺產,僅保留相容

WinExec("Notepad.exe", SW_SHOW);
WinExec("D:\\Program Files\\Test\\Test.exe", SW_SHOWMAXIMIZED);
// 路徑大小寫必須精確、無法獲取進程控制代碼、Microsoft 建議改用 CreateProcess

3. ShellExecute() - 文件/關聯操作首選

// 原型
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 執行、顯示模式控制。

4. CreateProcess() - 工業級完全控制

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

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_PROCESS
  • 偽裝身份:lpEnvironment 傳遞自訂環境變數、lpCurrentDirectory 指定工作目錄

選型決策樹

  1. 需開啟文件/URL/資料夾/列印 → ShellExecute
  2. 需啟動可執行檔、無進程控制需求 → ShellExecute (或 WinExec 相容舊碼)
  3. 需同步等待、獲取退出碼、重導向 IO、管道通訊、安全性控制 → CreateProcess
  4. 簡單批次/命令、不介意命令視窗閃現 → system (僅原型/測試)

安全性警示

  • system 透過 cmd.exe 解析,極易命令注入,**嚴禁**未驗證使用者輸入傳入
  • CreateProcess 直接建立進程,無 Shell 解析風險,參數分離傳遞最安全
  • 路徑含空格:CreateProcess 用 lpApplicationName 分離模組名,或命令列雙引號包裹
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved