C++調用外部程序

關於三個SDK函數:WinExec, ShellExecute,CreateProcess的其他注意事項:
【1】定義頭文件
必須定義以下兩個頭文件:

#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)、得不到啓動的程序的退出碼。
  (4)、不能運行*.txt文件或"www.baidu.com"

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");
    getchar();
    printf("Open a txt file\n");
    ShellExecute(NULL,"open","C:\\test.txt",NULL,NULL,SW_MINIMIZE);
    getchar();
    printf("Open a web\n");
    ShellExecute(NULL,NULL,"www.baidu.com",NULL,NULL,SW_SHOWNA);
    getchar();
    printf("Run a cmd command:ping www.sina.com\n");
    ShellExecute(NULL, NULL, "ping", "sina.com", NULL, SW_SHOWNORMAL);
    getchar();
    printf("打開目錄\n");
    ShellExecute(NULL, "open", "c:", NULL, NULL, SW_SHOWNORMAL);
    getchar();
    printf("瀏覽目錄\n");
    ShellExecute(NULL, "explore", "c:", NULL, NULL, SW_SHOWNORMAL);
    getchar();
    printf("文件屬性\n");
    ShellExecute(handle,"properties","C:\\test.txt",NULL,NULL,SW_MINIMIZE);
    printf("%s",handle);
   
}


四、C函數:

          1     system()
          2     spawn()   函數系列
          3     exec()   函數系列


發佈了27 篇原創文章 · 獲贊 13 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章