進程的創建
STARTUPINFO si; //**成員DWORD dwFlags;表示結構體當中哪些成員有效。**STARTF_USESHOWWINDOW|STARTF_USEPOSITION
PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); //LPTSTR pszCmdLine = TEXT("C:\\Windows\\System32\\notedap.exe");改成 //TCHAR pszCmdLine[] = TEXT("C:\\Windows\\System32\\notedap.exe"); //Windows核心編程專門有講這個問題 CreateProcess會修改傳遞給它的命令行字符串, LPTSTR是字符串指針不能修改....* / //char* szCommandLine ="C:\\Program Files (x86)\\KuGou\\KGMusic\\KuGou.exe";
TCHAR szCommandLine[] = TEXT("notepad ReadMe.txt");//父進程當前目錄下的ReadMe.txt
::CreateProcess(NULL,//可執行文件名(必須添加.exe。若未添加路徑則只會去當前目錄找。so一般為NULL)
(LPWSTR)szCommandLine,//傳遞給執行模塊的參數,相當於在運行欄輸入szCommandLine(可以在一些目錄下自動搜尋exe)
NULL,//進程安全性
NULL, //線程安全性
FALSE,//當前進程的可繼承句柄是否可以被新進程繼承
NULL,//創建標志 如 CREAT_NEW_CONSOLE
NULL, //環境變量
NULL,//當前目錄
&si,//父給子進程的顯示信息
&pi);//此進程的標志信息 ID\句柄
&pi.dwProcessId;//進程ID
&pi.dwThreadId;//進程中主線程ID
&pi.hProcess;//進程內核句柄
&pi.hThread;//進程中主線程內核句柄
終止進程
//::ExitProcess(0); //終止當前進程,退出代碼0 //BOOL bBet=::TerminateProcess(pi.hProcess,-1);//退出代碼-1(關閉進程失敗)
HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, //想得到的訪問權限
FALSE, //返回的句柄是否可以被繼承
pi.dwProcessId);//進程ID
BOOL bBet = ::TerminateProcess(hProcess, -1);//(關閉進程成功)
CloseHandle(hProcess); CloseHandle(pi.hProcess); //不使用就關閉
創建線程
DWORD dwThreadId; HANDLE hHandle; hHandle = ::CreateThread(NULL, //線程安全屬性
NULL, //線程堆棧大小
ThreadFun, //線程函數起始地址
NULL, //傳給線程函數的參數
0, //是否立即啟動線程
&dwThreadId);//取得線程ID //一般使用下面方法
UINT uId; HANDLE hHandleCopy; hHandleCopy = (HANDLE)::_beginthreadex(NULL, //線程安全屬性
NULL, //線程堆棧大小
ThreadProc, //線程函數起始地址
NULL, //傳給線程函數的參數
0, //是否立即啟動線程
&uId);//取得線程ID
線程函數如下:
//============================================================================================ //線程函數的定義 //DWORD WINAPI ThreadFun() //參數LPVOID IpParam是必須的
DWORD WINAPI ThreadFun(LPVOID IpParam) { STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); TCHAR szCommandLine[] = TEXT("C:\\Program Files (x86)\\KuGou\\KGMusic\\KuGou.exe"); ::CreateProcess(NULL,(LPWSTR)szCommandLine,NULL,NULL,FALSE,NULL,NULL, NULL,&si,&pi); return 0; } //=============================================================================================
UINT _stdcall ThreadProc(LPVOID IpParam) { ::WaitForSingleObject(g_hEvent,INFINITE); STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); TCHAR szCommandLine[] = TEXT("notepad ReadMe.txt"); ::CreateProcess(NULL, (LPWSTR)szCommandLine, NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi); return 0; } //================================================================================================
線程通信交互
//線程之間的交互(事件內核對象) //HANDLE g_hEvent;
g_hEvent = ::CreateEvent(NULL, //事件對象安全屬性
FALSE, //是否是手動重置事件對象為未受信(否則系統自動重置)
FALSE, //初始狀態(受信/未受信)執行中:未受信
NULL); //事件對象名稱(可用於OpenEvent()函數的第三個參數,類似進程)
::WaitForSingleObject(hHandle, //對象句柄
INFINITE); //等待時間(\毫秒)
Sleep(10000); SetEvent(g_hEvent); //RetEvent(g_hEvent); //自動模式下無需重置(自動重置)
::WaitForSingleObject(hHandleCopy,INFINITE); //等待 //::WaitForMultipleObjects(2, //對象句柄數量 // h, //對象句柄數組 // TRUE, //是否等待所有內核對象變為受信狀態(否則有一個就可以) // INFINITE) //等待時間(\毫秒) //很實用,等待指定線程執行完畢(不加這句線程還未執行完畢主線程就已經結束了)
其中SetEvent(g_hEvent);中的g_hEvent是全局變量HANDLE g_hEvent;
SetEvent(g_hEvent)使得事件對象g_hEvent變為受信狀態,
此時ThreadProc函數中的::WaitForSingleObject(g_hEvent,INFINITE);函數檢測到其為受信時開始執行接下來的代碼。
終止線程與終止進程類似,一般不使用終止進程和線程函數,一般使用通信機制告訴要關閉的進程或線程讓其自行退出。
強行終止會使得來不及執行析構函數,回收內存,造成內存泄漏。