這裡我再次說明一下,我不知道為什麼,現在的人那麼喜歡走極端,估計是價值觀都“升級”了的 緣故吧。
我撰寫這一系列Win32相關的文章,並不是叫大家一定要用Win32去開發項目,僅僅是 給大家了解一下,Win32是個啥東西而已。
另外,在專訪中,有些人也誤認為我說C++非學不可 ,那也不是,我也提到過了,C++的學習可以使你懂得更多知識,為你以為學習各種技術打下基礎。
今天,我們來了解一下,在應用程序中,如何啟動一個進程,然後把這個進程結束掉。實現這 一功能有替代方案,即使用.NET庫中的System::Diagnostics::Process類來完成。在Win32中,啟動一 個進程可以理解為創建進程,所以可以調用CreateProcess函數,結束進程則調用TerminateProcess函 數。
唯一標識一個進程的是PID,而我們要對進程進行各項操作,進程也存在於內存中,也可以 視為一種資源,我們知識,操作圖標資源有HICON,操作位圖資源有HBITMAP,同樣道理,對進程所作的 操作也要通過一個標識符(句柄)——HANDLE。
CreateProcess函數的最後一個參數是一個指向 PROCESS_INFORMATION結構體的指針,該結構的成員可以保存被創建進程的ID和句柄。
typedef struct _PROCESS_INFORMATION { HANDLE hProcess; //進程的句柄 HANDLE hThread; //主線程的句柄 DWORD dwProcessId; //進程ID DWORD dwThreadId; //主線程ID } PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;
接下來我們要 對已創建進程進行的一系列操作,都以hProcess為紐帶,包括獲取退出碼和終止進程。
CreateProcess函數的最後兩個參數都是指針,因此我們在使用時,要先定義STARTUPINFO和 PROCESS_INFORMATION類型的變量,並使用ZeroMemory函數將其成員初始化。ZeroMemory函數可以將一 段內存中的數據初始化為0.
示例代碼如下:
PROCESS_INFORMATION pro_info; //進程 信息 STARTUPINFO sti; //啟動信息 //...... // 初始化兩個結構體 ZeroMemory(&pro_info, sizeof(PROCESS_INFORMATION)); ZeroMemory(&sti, sizeof(STARTUPINFO));
接著調用CreateProcess創建進程.
CreateProcess(L"C:\\Windows\\System32 \\calc.exe",NULL,NULL,NULL,FALSE,0,NULL,NULL,&sti,&pro_info);
調用成功後,PROCESS_INFORMATION結構體的hProcess就保存了被創建的進程的句柄了。
要結 束進程,調用TerminateProcess函數,第一個參數就是剛才創建的時程的句柄,第二個參數是退出碼, 通過GetExitCodeProcess函數可以獲取。
DWORD exitCode; //退出碼 //......... GetExitCodeProcess(pro_info.hProcess,&exitCode); //獲取退出碼 TerminateProcess(pro_info.hProcess, exitCode); // 關閉句柄 CloseHandle(pro_info.hThread); CloseHandle(pro_info.hProcess);
下面是這個示例的運行結果圖,完整的代碼我稍後上傳到 資源區中。
另外,再介紹一個在應用程序中運行其他程序的方法,那就是使 用Shell函數——ShellExecute。
HINSTANCE ShellExecute( _In_opt_ HWND hwnd, _In_opt_ LPCTSTR lpOperation, _In_ LPCTSTR lpFile, _In_opt_ LPCTSTR lpParameters, _In_opt_ LPCTSTR lpDirectory, _In_ INT nShowCmd );
我們這裡只是運行一個程序,沒有其他操作,所以,帶 _In_opt_的可選參數可以直接NULL ,lpFile指定我們要運行程序的路徑,如果是一個exe文件,那lpParameters可以指定命令行參數,但 我們這裡不需要,所以繼續NULL,最後一個參數好理解,和ShowWindow函數一樣。
於是,用 ShellExecute函數打開記事本程序,當然記得包含shellapi.h。
ShellExecute(NULL,NULL,L"C:\\Windows\\System32 \\notepad.exe",NULL,NULL,SW_SHOWNORMAL);
看看結果,和前面效果差不多。