C/C++使用WinAPI CreateProcess函數調用外部程序

CreateProcess函數原型:

BOOL WINAPI CreateProcess(
  _In_opt_     LPCTSTR lpApplicationName,
  _Inout_opt_  LPTSTR lpCommandLine,
  _In_opt_     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  _In_opt_     LPSECURITY_ATTRIBUTES lpThreadAttributes,
  _In_         BOOL bInheritHandles,
  _In_         DWORD dwCreationFlags,
  _In_opt_     LPVOID lpEnvironment,
  _In_opt_     LPCTSTR lpCurrentDirectory,
  _In_         LPSTARTUPINFO lpStartupInfo,
  _Out_        LPPROCESS_INFORMATION lpProcessInformation
);

查看微軟官方說明:https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx

示例代碼:

# include <stdio.h>
# include <Windows.h>

/*
函數原型:
BOOL WINAPI CreateProcess(
  _In_opt_     LPCTSTR lpApplicationName,
  _Inout_opt_  LPTSTR lpCommandLine,
  _In_opt_     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  _In_opt_     LPSECURITY_ATTRIBUTES lpThreadAttributes,
  _In_         BOOL bInheritHandles,
  _In_         DWORD dwCreationFlags,
  _In_opt_     LPVOID lpEnvironment,
  _In_opt_     LPCTSTR lpCurrentDirectory,
  _In_         LPSTARTUPINFO lpStartupInfo,
  _Out_        LPPROCESS_INFORMATION lpProcessInformation
);
*/

int main(int argc, char * argv[])
{
    TCHAR commandLine[] = TEXT("notepad");
    STARTUPINFO si = {sizeof(si)};
    PROCESS_INFORMATION pi;
    bool bRet = CreateProcess(
        NULL,
        commandLine,
        NULL,
        NULL,
        FALSE,
        CREATE_NO_WINDOW,
        NULL,
        NULL,
        &si,
        &pi);
    int error = GetLastError();
    if (bRet)
    {
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);

        printf("進程ID:%d\n", pi.dwProcessId);
        printf("線程ID:%d\n", pi.dwThreadId);
    }
    system("pause");
    return 0;
}

運行效果:
這裏寫圖片描述

NOTE:

TCHAR * commandLine = TEXT("notepad");//這裏用了指向字符串的指針
    STARTUPINFO si = {sizeof(si)};
    PROCESS_INFORMATION pi;
    bool bRet = CreateProcess(
        NULL,
        commandLine,
        NULL,
        NULL,
        FALSE,
        CREATE_NO_WINDOW,
        NULL,
        NULL,
        &si,
        &pi);

//TCHAR commandLine[] = TEXT("notepad");
    STARTUPINFO si = {sizeof(si)};
    PROCESS_INFORMATION pi;
    bool bRet = CreateProcess(
        NULL,
        TEXT("notepad"),
        NULL,
        NULL,
        FALSE,
        CREATE_NO_WINDOW,
        NULL,
        NULL,
        &si,
        &pi);

以上兩種用法都不能編譯通過。這是因爲在內部,CreateProcess實際上會修改我們傳給他的命令行字符串,不過在這個函數返回前,會把這個字符串還原,所以這樣的代碼是錯誤的。

如果使用了lpApplicationName參數傳遞了可執行程序,那麼lpCommandLine參數前必須有個空格;

TCHAR * appPath = TEXT("\"c:\\program files (x86)\\internet explorer\\iexplore.exe\"");
    TCHAR cmdline[] = TEXT(" http://www.baidu.com");    //http前有空格
    STARTUPINFO si = {sizeof(si)};
    PROCESS_INFORMATION pi;

如果可執行程序路徑中如果有空格,須用雙引號括起。如果不用雙引號括起會產生調用錯誤,如下代碼:

TCHAR cmdline[] = TEXT("c:\\program files (x86)\\internet explorer\\iexplore.exe);
//這裏會打開C盤下program.exe程序,如果存在,而不是iexplore.exe
CreateProcess(      
        NULL,       
        cmdline,
        //這裏會打開C盤下program.exe程序,如果存在,而不是iexplore.exe
        NULL,
        NULL,
        FALSE,
        CREATE_NEW_CONSOLE,
        NULL,
        NULL,
        &si,
        &pi);

lpCommandLine參數不能直接傳遞字符串。像這樣調用是錯誤的:

CreateProcess(      
        NULL,       
        TEXT("\"c:\\program files (x86)\\internet explorer\\iexplore.exe\" http://www.baidu.com"),
        NULL,
        NULL,
        FALSE,
        CREATE_NEW_CONSOLE,
        NULL,
        NULL,
        &si,
        &pi);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章