天天看點

【VS開發】C++調用外部程式

關于三個SDK函數:WinExec, ShellExecute,CreateProcess的其他注意事項:

【1】定義頭檔案

必須定義以下兩個頭檔案:

[cpp] ​​view plain​

​ ​​copy​​

#include <shlobj.h> // 可替換為 windows.h  

#include <shellapi.h>  

如果定義了頭檔案 #include <windows.h>的話就不必定義 #include <shlobj.h>了。

【2】定義路徑

C++中所表示的路徑要用 " \\ "而不是平常所用的" \ ",是以以上三個函數表示路徑都為:disk:\\Directory\\...\\Filename

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

ShellExecute(NULL,"open","C:\\Test.txt",NULL,NULL,SW_SHOWNORMAL);  

1、調用API: int system( const char *command );

  你可以傳入一指令,啟動某個程式。如"ping ​​www.vccode.com​​", "YourExe"等等

  不過這裡有幾點要值得注意:

  (1)、他不會立即傳回,直到你啟動的程式執行完成。

  (2)、如果你啟動是windows程式,它仍然會啟動一個控制台,這就給人感覺太差勁了,但如果本身是控制台的,而且又需要等待它的完成,那這将是比較好的選擇。

  (3)、它的傳回值代表是否執行成功以及程式的退出碼。

  (4)、不能運作*.txt檔案或"​​www.baidu.com​​"

2、調用API:

UINT WinExec(  

 LPCSTR lpCmdLine, // command line  

 UINT uCmdShow // window style  

);  

  這個API與API:system同樣的使用簡單,同用是使用指令行型式。

  不過它與API:system相比,有幾個優點:

  (1)、它将啟動了一個新程序,并且立即傳回,是以你的程式無需等待。

  (2)、它的多了一個參數:uCmdShow,通過它你可以一定程度上控件窗體的顯示,比如讓它背景運作而不顯示出來。

  (3)、它無論啟動控制台程式還是windows程式都隻做你想要做的事。

  它的不足之處:

  (1)、它完全與本程序脫離,無法對做些必要的控制

  (2)、無法得知啟動的程式是否退出。

  (3)、得不到啟動的程式的退出碼。

3、調用:

  

HINSTANCE ShellExecute(  

   HWND hwnd,  

   LPCTSTR lpVerb,  

   LPCTSTR lpFile,  

   LPCTSTR lpParameters,  

   LPCTSTR lpDirectory,  

   INT nShowCmd  

  );  

    它也有WinExec同樣的缺點。

  它雖然傳回一個HINSTANCE,但他并不是真正的句柄,我們僅能拿它來做一些錯誤值檢查。

  但它的功能比前兩者更強大,它執行系統的Shell指令。

  1、2中如果傳入“XX.txt”,它們将不能成功執行,ShellExecute卻能很好地執行,它将啟動一個預設的文字處理程式來打開它。

  1、2中如果傳入“www.vccode.com”,将不能成功執行,而ShellExecute卻能很好地執行,它将啟動一個預設浏覽器來打開這個網站。

  參數講解:

  參數1 hwnd:一窗體句柄,将作為啟動的程式的父窗體。

  參數2 lpVerb:你想執行的操作(edit 、explore、find、open、print、properties),你也可以傳入NULL值,它将執行預設操作(win2000以前與以後處理略有差别,請見MSDN)。

  參數3 lpFile:一檔案名或操作的對象。

  參數4 lpParameters:如果lpFile是一可執行檔案,這個将作為它的參數。它的格式由執行的操作決定。而且當lpFile為一document檔案時,此參數需為NULL。

  參數5 lpDirectory:指定它的工作目錄。

  參數6 nShowCmd:窗體顯示的控制。

  以下是幾個例子:

//啟動一個Dos指令, 啟動windows程式相同  

  ::ShellExecute(this->GetSafeHwnd(), NULL,"ping", "www.vccode.com",NULL, SW_SHOWNORMAL);  

  //打開一個檔案  

  ::ShellExecute(this->GetSafeHwnd(),"open", "ReadMe.txt", NULL, NULL, SW_SHOWNORMAL);  

  //上面的動詞可傳可不傳,但如果"ReadMe.txt"為"ReadMe.bat"那就得指定,否則将會當指令執行,而不是打開它。  

  //可打開目錄  

  ::ShellExecute(this->GetSafeHwnd(),"open", "c:", NULL, NULL, SW_SHOWNORMAL);  

  //可打開網頁  

  ::ShellExecute(this->GetSafeHwnd(),"open", "www.vccode.com",NULL, NULL, SW_SHOWNORMAL);  

   

  //浏覽一個目錄  

  ShellExecute(handle, "explore","c:"NULL, NULL, SW_SHOWNORMAL);  

  //檢視一個檔案或目錄的屬性  

  //使用ShellExecuteEx,實作請見所附源碼對應部分  

  如果沒有特殊的控制要求,它己能為我們做很了,但當我們一定要能控件這個啟動的程序時,那我們就得使用第4點了。

4:調用API:

BOOL CreateProcess(  

   LPCTSTR lpApplicationName, // name of executablemodule  

   LPTSTR lpCommandLine, // command line string  

   LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD  

   LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD  

   BOOL bInheritHandles, // handle inheritance option  

   DWORD dwCreationFlags, // creation flags  

   LPVOID lpEnvironment, // new environment block  

   LPCTSTR lpCurrentDirectory, // current directoryname  

   LPSTARTUPINFO lpStartupInfo, // startup information  

   LPPROCESS_INFORMATION lpProcessInformation //process information  

  往往看到這個函數就讓人生畏,它參數多,而且參數類型也如此莫生。是的,正是因為如此它才功能強大!

  但不要怕,作為一般使用,非常簡單!下面便是一個簡單的例子(啟動記事本):

STARTUPINFO StartInfo;  

PROCESS_INFORMATION pinfo;  

//對程式的啟動資訊不作任何設定,全部清0  

memset(&StartInfo,0,sizeof(STARTUPINFO));  

StartInfo.cb = sizeof(STARTUPINFO);//設定結構的大小  

BOOL ret=CreateProcess(  

 NULL, //啟動程式路徑名  

 "notepad.exe", //參數(當exeName為NULL時,可将指令放入參數前)  

 NULL, //使用預設程序安全屬性  

 NULL, //使用預設線程安全屬性  

 FALSE,     //句柄不繼承  

 NORMAL_PRIORITY_CLASS, //使用正常優先級  

 NULL, //使用父程序的環境變量  

 NULL, //指定工作目錄  

 &StartInfo, //子程序主視窗如何顯示  

 &pinfo); //用于存放新程序的傳回資訊  

  這樣在建立成功這後我們就可以從pinfo中找到它的:程序句柄,線程句柄,程序ID,線程ID

  在附件源碼中示範了程序式的啟動,停止。

  實際上我們可以通過很多方式如記憶體共享、父程序窗體句體傳入仍後從消息中獲得子程序窗體句柄等,來實作更多的控制。

  想很好地掌握CreateProcess,可參見人民郵電出版社出版的<< Windows系統程式設計 >>,它的“程序”部份作了很詳盡的說明。 

         例程:

#include<windows.h>  

#include<shellapi.h>  

#include<stdio.h>  

void main()  

{  

    HWND handle;  

    printf("Function <WinExec>:\nIt can run a cmd command,but can`t open *.txt and \"www.*.*\"\n");  

    printf("Please press Enter go on\n");  

    getchar();  

    WinExec("mspaint.exe",SW_SHOWNOACTIVATE);  

    printf("Function <ShellExecute>:\nIt can run a cmd command to open file or web\n\n");  

    printf("Open a txt file\n");  

    ShellExecute(NULL,"open","C:\\test.txt",NULL,NULL,SW_MINIMIZE);  

    printf("Open a web\n");  

    ShellExecute(NULL,NULL,"www.baidu.com",NULL,NULL,SW_SHOWNA);  

    printf("Run a cmd command:ping www.sina.com\n");  

    ShellExecute(NULL, NULL, "ping", "sina.com", NULL, SW_SHOWNORMAL);  

    printf("打開目錄\n");  

    ShellExecute(NULL, "open", "c:", NULL, NULL, SW_SHOWNORMAL);  

    printf("浏覽目錄\n");  

    ShellExecute(NULL, "explore", "c:", NULL, NULL, SW_SHOWNORMAL);  

    printf("檔案屬性\n");  

    ShellExecute(handle,"properties","C:\\test.txt",NULL,NULL,SW_MINIMIZE);  

    printf("%s",handle);  

}  

四、C函數:

          1     system() 

          2     spawn()   函數系列 

          3     exec()   函數系列