關於三個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() 函數系列