有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);