在程序運行過程中調用另一個程序


有3個函數可以使用:WinExec、ShellExecute、CreateProcess

1、WinExec

  這個函數最簡單,只有兩個參數,原型如下:

  UINT WinExec(
    LPCSTR lpCmdLine,
    UINT uCmdShow
  );

  lpCmdLine:指向一個空結束的字符串,串中包含將要執行的應用程序的命令行(文件名加上可選參數)。

  uCmdShow:定義Windows應用程序的窗口如何顯示:SW_HIDE、SW_MINIMIZE、SW_RESTORE、SW_SHOW、SW_SHOWMAXIMIZED、SW_SHOWMINIMIZED、SW_SHOWMINNOACTIVE、SW_SHOWNA、SW_SHOWNOACTIVATE、SW_SHOWNORMAL;

  返回值:

  若函數調用成功,則返回值大於31。若函數調用失敗,則返回值為下列之一:

  ① 0:系統內存或資源已耗盡。

  ② ERROR_BAD_FORMAT:EXE文件無效(非Win32.EXE或.EXE影像錯誤)。

  ③ ERROR_FILE_NOT_FOUND:指定的文件未找到。

  ④ ERROR_PATH_NOT_FOUND:指定的路徑未找到。

  雖然Microsoft認為WinExec已過時,但是在許多時候,簡單的WinExec函數仍是運行新程序的最好方式。簡單地傳送作為第一個參數的命令行,還需要決定如何顯示程序(該程序也許會忽視它)的第二個參數。WinExec不允許用CreateProcess獲得的所有選項,而它的確簡單。

  使用方法如下:

  WinExec(_T("D:\\Program Files\\abc\\abc.exe"),SW_SHOWMAXIMIZED);

  WinExec("Notepad.exe", SW_SHOW);  // 打開記事本

  WinExec("D:/Program Files/01/01.exe",SW_SHOWMAXIMIZED);

  需要注意的是若用 SW_SHOWMAXMIZED 方式去加載一個無最大化按鈕的程序,譬如Neterm,Calc 等等,就不會出現正常的 窗體,但是已經被加到任務列表里了。

2、ShellExecute

  ShellExecute比WinExex靈活一點,所以參數就要多一點,原型如下:

  HINSTANCE ShellExecute(

    HWND hwnd, //父窗口句柄

    LPCTSTR lpOperation,//打開方式

    LPCTSTR lpFile, //待打開的文件名,前面可加路徑

    LPCTSTR lpParameters, //參數

    LPCTSTR lpDirectory, //默認文件路徑

    INT nShowCmd //顯示方式

   );

  hwnd:指向父窗口的窗口句柄。此窗口接收應用程序產生的任何信息框。

  lpOperation:此字符串指定要執行的操作:

    "open" 此函數打開由參數lpFile指定的文件,此文件可以是一個可執行文件或文檔文件,也可是一個文件夾。

    "print" 此函數打印由參數lpFile指定的文件,此文件應是一個文檔文件,假如此文件是一個可執行文件,則打開此文件。

    "explore" 此函數搜索由參數lpFile指定的文件夾,此文件應是一個文檔文件,

    此參數可以為空。這種情況下,函數默認用於打開"open"由參數lpFile指定的文件。

  lpFile:指定要打開或打印的文件或者是要打開或搜索的文件夾。

  lpParameters:假如參數lpFile指定一個可執行文件,lpParameters指定要傳遞給應用程序的參數。假如lpFile指定一個文檔文件,lpParameters應為空。

  lpDirectory:指定默認目錄。

  nShowCmd:假如lpFile指定一個可執行文件,nShowCmd表明應用程序打開時如何顯示。假如lpFile指定一個文檔文件,nShowCmd應為空。

  返回值:

  若函數調用成功,則返回值大於32,否則為一個小於等於32的錯誤值。

  使用方法:

  ShellExecute(NULL,_T("open"),_T("abc.exe"),NULL,_T("D:\\Program Files\\abc\\"),SW_SHOWNORMAL);

  ShellExecute(NULL, ''open'', ''c:\\test\\readme.txt'', nll, nll, SW_SHOW);

  ShellExecute(NULL,"explore", "D:/C++",NULL,NULL,SW_SHOWNORMAL); // 打開目錄D:/C++

  ShellExecute(NULL,"print","C:/Test.txt",NULL,NULL, SW_HIDE); // 打印文件C:/Test.txt

 

  ShellExecuteEx:這個windows函數用的不多,但是要手動提升進程的權限時,就要用這個函數。

  用法:

    SHELLEXECUTEINFO sei = {sizeof(SHELLEXECUTEINFO)};  

    sei.lpVerb = TEXT("runas");   //“runas”表示使用管理員權限運行。

    sei.lpFile = TEXT("abc.exe"); 

    //sei.lpDirectory = TEXT("C:\\abc");

 

    sei.nShow = SW_SHOWNORMAL; 

    if (!ShellExecuteEx(&sei))  

    { 

      DWORD dwError = GetLastError(); 

      if(dwError==ERROR_CANCELLED) 

      { 

        printf("提升權限被用戶拒絕\n"); 

      } 

      else if(dwError==ERROR_FILE_NOT_FOUND) 

      { 

        printf("所要執行的文件沒有找到\n"); 

      }

    }

 

3、CreateProcess

  BOOL CreateProcess(

    LPCTSTR lpApplicationName, //執行程序名

    LPTSTR lpCommandLine, // 參數行

    //下面兩個參數描述了所創建的進程和線程的安全屬性,如果為NULL則使用默認的安全屬性
    LPSECURITY_ATTRIBUTES lpProcessAttributes, // process security attributes
    LPSECURITY_ATTRIBUTES lpThreadAttributes, // thread security attributes

    BOOL bInheritHandles, // 繼承標志

    DWORD dwCreationFlags, // 創建標志

    LPVOID lpEnvironment, // 環境變量

    LPCTSTR lpCurrentDirectory, // 運行該進程的初始目錄

    LPSTARTUPINFO lpStartupInfo, // 用於在創建子進程時設置各種屬性

    LPPROCESS_INFORMATION lpProcessInformation //用於在進程創建后接受相關信息
  );

  lpApplicationName:指定了要執行的模塊

  lpCommandLine:定義了要執行的命令行。

  lpProcessAttributes:指向一個SECURITY_ATTRIBUTES結構,該結構決定了返回的句柄是否可被子進程繼承。

  lpThreadAttributes:指向一個SECURITY_ATTRIBUTES結構,該結構決定了返回的句柄是否可被子線程繼承。

  bInheritHandles,:表明新進程是否從調用進程繼承句柄。

  dwCreationFlags:定義控制優先類和進程創建的附加標志。

  lpEnvironment:指向一個新進程的環境塊。

  lpCurrentDirectory:定義了子進程的當前驅動器和當前目錄。

  lpStartupInfo:指向一個STARTUPINFO結構,該結構定義了新進程的主窗口將如何顯示。

  lpProcessInformation:指向PROCESS_INFORMATION結構,該結構接受關於新進程的表示信息。

 

  在上面的參數中,使用了兩個比較重要的數據結構:STARTUPINFO和PROCESS_INFORMATION。這兩個結構的定義分別如下:

  typedef struct _STARTUPINFO {   // si
    DWORD cb; //結構長度
    LPTSTR lpReserved; //保留
    LPTSTR lpDesktop; //保留
    LPTSTR lpTitle; //如果為控制台進程則為顯示的標題
    DWORD dwX; //窗口橫坐標
    DWORD dwY; //窗口叢坐標
    DWORD dwXSize; //窗口寬度
    DWORD dwYSize; //窗口高度
    DWORD dwXCountChars; //控制台窗口字符號寬度
    DWORD dwYCountChars; //控制台窗口字符號高度
    DWORD dwFillAttribute; //控制台窗口填充模式
    DWORD dwFlags; //創建標記
    WORD wShowWindow; //窗口顯示標記,如同ShowWindow中的標記

    WORD cbReserved2; //保留參數
    LPBYTE lpReserved2; //保留參數
    HANDLE hStdInput; //標准輸入句柄
    HANDLE hStdOutput; //標准輸出句柄
    HANDLE hStdError; //標准錯誤句柄
  } STARTUPINFO, *LPSTARTUPINFO;

  typedef struct _PROCESS_INFORMATION {    // pi
    HANDLE hProcess; //進程句柄
    HANDLE hThread; //進程的主線程句柄
    DWORD dwProcessId; //進程的ID
    DWORD dwThreadId; //進程的主線程ID
  } PROCESS_INFORMATION;

  

  在上述參數中,參數lpStartupInfo是STARTUPINFO結構。可以用來設置控制台的標題,新窗口的的初始大小和位置,及重定向標准輸入和輸出。參數lpProcessInformation返回進程和線程句柄,還包括進程和線程ID。這些句柄須擁有在參數lpProcessAttributes和lpThreadAttributes中規定的訪問權。

 

  返回值:

  若函數調用成功,則返回值不為0;若函數調用失敗,返回值為0。

  使用方法:

    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    memset(&si,0,sizeof(si));
    si.cb=sizeof(si);
    si.wShowWindow=SW_SHOW;
    si.dwFlags=STARTF_USESHOWWINDOW;

    bool fRet=CreateProcess("D:\\Program Files\\abc\\abc.exe",NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM