實現守護進程

守護進程的大體思路就是用一個線程函數,一段時間去檢測某個進程是否還存在,存在則不管,不存在則重啓,或者進程是否屬於掛起狀態,掛起的話也是重啓程序(先kill掉進程,然後重新啓動)

1.創建線程

HANDLE hThread1;
	DWORD dwThreadId1;
	try
	{
		hThread1 = CreateThread(NULL,0,DoThread,this,0,&dwThreadId1);
	}
	catch (CMemoryException* e)
	{

	}
	catch (CFileException* e)
	{
	}
	catch (CException* e)
	{
	}
	if (hThread1!=NULL)
	{
		CloseHandle(hThread1);
	}	

2.進程檢測

HINSTANCE hDll = LoadLibrary(_T("user32.dll"));
	CString m_szStatus;
	while(1)
	{
		CWnd* hwnd = CWnd::FindWindow(NULL, TEXT("dataGet"));// m_szName 程序名稱

		if (NULL != hwnd)
		{
			if (NULL != hDll)
			{
				typedef BOOL(WINAPI *PROCISHUNGAPPWINDOW)(HWND); 
				PROCISHUNGAPPWINDOW IsHungAppWindow = (PROCISHUNGAPPWINDOW)GetProcAddress(hDll, "IsHungAppWindow");
				if (IsHungAppWindow(hwnd->GetSafeHwnd()))
				{
					//先殺掉進程,然後在開啓
					KillerProcess(TEXT("dataGet.exe"));
					m_szStatus =TEXT( "未響應");
					RunTheSysProc();
					Sleep(1500);
					//發送採集消息
					CWnd* hwnd_ = CWnd::FindWindow(NULL, TEXT("dataGet"));// m_szName 程序名稱
					::PostMessage(hwnd_->GetSafeHwnd(),WM_COMMAND, MAKEWPARAM(IDC_BTN_GETD, BN_CLICKED), 0);
				}
				else
				{
					m_szStatus = TEXT("正在運行");
				}
			}
		}
		else
		{
			m_szStatus = TEXT("未檢測到程序狀態!");
			RunTheSysProc();
			Sleep(1500);
			//發送採集消息
			CWnd* hwnd_ = CWnd::FindWindow(NULL, TEXT("dataGet"));// m_szName 程序名稱
			::PostMessage(hwnd_->GetSafeHwnd(),WM_COMMAND, MAKEWPARAM(IDC_BTN_GETD, BN_CLICKED), 0);
		}

		Sleep(5000);
	}

3.啓動線程

TCHAR    szPath[MAX_PATH];
	GetModuleFileName(NULL, szPath, MAX_PATH);
	CString strPath = szPath;
	strPath = strPath.Left(strPath.ReverseFind('\\')) + TEXT("\\dataGet.exe");

	STARTUPINFO            StartInfo;
	PROCESS_INFORMATION    procStruct;
	memset(&StartInfo,0,sizeof(STARTUPINFO));
	StartInfo.cb = sizeof(STARTUPINFO);

	if(!::CreateProcess(
		(LPCTSTR) strPath,
		NULL,
		NULL,
		NULL,
		FALSE,
		NORMAL_PRIORITY_CLASS,
		NULL,
		NULL,
		&StartInfo,
		&procStruct))
		return false;
	return true;

4.kill進程

//創建進程快照(TH32CS_SNAPPROCESS表示創建所有進程的快照)
	HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
	//PROCESSENTRY32進程快照的結構體
	PROCESSENTRY32 pe;

	//實例化後使用Process32First獲取第一個快照的進程前必做的初始化操作
	pe.dwSize = sizeof(PROCESSENTRY32);


	//下面的IF效果同:
	//if(hProcessSnap == INVALID_HANDLE_VALUE)   無效的句柄
	if(!Process32First(hSnapShot,&pe))
	{
		return FALSE;
	}

	//將字符串轉換爲小寫
	strProcessName.MakeLower();

	//如果句柄有效  則一直獲取下一個句柄循環下去
	while (Process32Next(hSnapShot,&pe))
	{

		//pe.szExeFile獲取當前進程的可執行文件名稱
		CString scTmp = pe.szExeFile;


		//將可執行文件名稱所有英文字母修改爲小寫
		scTmp.MakeLower();

		//比較當前進程的可執行文件名稱和傳遞進來的文件名稱是否相同
		//相同的話Compare返回0
		if(!scTmp.Compare(strProcessName))
		{
			//從快照進程中獲取該進程的PID(即任務管理器中的PID)
			DWORD dwProcessID = pe.th32ProcessID;
			HANDLE hProcess = ::OpenProcess(PROCESS_TERMINATE,FALSE,dwProcessID);
			::TerminateProcess(hProcess,0);
			CloseHandle(hProcess);
			return TRUE;
		}
		scTmp.ReleaseBuffer();
	}
	strProcessName.ReleaseBuffer();
	return FALSE;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章