守護進程的大體思路就是用一個線程函數,一段時間去檢測某個進程是否還存在,存在則不管,不存在則重啓,或者進程是否屬於掛起狀態,掛起的話也是重啓程序(先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;