如何检测一个进程及其产生的所有线程的状态是否正常?
如何检测一个进程及其产生的所有线程的状态是否正常?比如某个程序执行了非法操作,或由其产生的线程执行了非法操作(此时主线程仍可正常运行),有没有一个方法检测出来?
我这样做的目的是:在服务器上运行了一个服务程序A.exe 需要监控A.exe的运行情况,发现它出错时(如崩溃)能够把它终止,然后自动重起服务。
我现在的做法是:
写了一个监测程序为B.exe
B.exe完成这样一个功能:
1. 每隔一段时间检测一下系统的所有窗口进程(例如10秒)
利用EnumWindows()得到的窗口句柄。判断是否为错误报警的窗口发生。
错误报警的窗口的标题一般都有:"某某程序执行了非法操作"的字样。
2. 一旦确定下来,就可将其关闭再重新启动。
程序段如下:
BOOL CZCallDetectorDlg::FindErrorWindow(HWND hwnd)
{
// 添加类名
CString strWinName;
::GetClassName(hwnd, strWinName.GetBuffer(STRINGLEN), STRINGLEN);
// 用GetWindowText添加窗口文本
DWORD result;
SendMessageTimeout(hwnd,
WM_GETTEXT,
STRINGLEN,
(LPARAM)strWinName.GetBuffer(STRINGLEN),
0,
1000,
&result);
strWinName.MakeLower();
m_strWindowName.MakeLower();
if( strstr(strWinName,m_strWindowName) && strWinName.CompareNoCase( m_strzCallName) ) // Exist Error Window?
{
::PostMessage(hwnd,WM_COMMAND,IDOK,NULL) );
::PostMessage(hwnd,WM_CLOSE,NULL,NULL) );
strWinName.ReleaseBuffer();
return TRUE;
}
else
{
strWinName.ReleaseBuffer();
return FALSE;
}
return FALSE;
}
但是运行测试过程中:
1、我把A.exe和B.exe都通过远程桌面在远程服务器上运行,并且让A.exe出现了错误提示,即弹出“A.exe-应用程序错误”这个窗口
2、使用EnumWindows已经找到了该窗口,也就是程序已经执行到了::PostMessage(hwnd,WM_COMMAND,IDOK,NULL) 这里
但是出现了这样的问题:
我把远程桌面窗口打开的时候,::PostMessage(hwnd,WM_COMMAND,IDOK,NULL)能够把“A.exe-应用程序错误”这个窗口关掉,但如果把远程桌面的窗口最小化或者关掉,::PostMessage(hwnd,WM_COMMAND,IDOK,NULL)就不起作用了,这时就不能把错误窗口关掉!!!
--请教高手这样古怪的问题如何解决?
--一般的服务监控程序是如何作的?
问题点数:100、回复次数:9Top
1 楼DentistryDoctor(不在无聊中无奈,就在沉默中变态)回复于 2006-03-01 19:02:39 得分 0
关键是应该首先解决崩溃的问题。Top
2 楼cnwolf(独狼)回复于 2006-03-01 19:27:39 得分 0
我觉得一般服务监控,应该是定时检查服务进程
如果不在了就重新创建Top
3 楼cdutgch(欢喜游龙)回复于 2006-03-02 08:48:17 得分 0
但是在出现了 弹出“A.exe-应用程序错误”这个窗口 的时候,如何才能自动把它关掉?!Top
4 楼sboom(+-LingCh-+)(爱美人不爱VC)回复于 2006-03-02 15:14:25 得分 0
仿网络的心跳包啊,写一个监控线程,所有工作线程隔一段时间向监控线程汇报他还活着。Top
5 楼Atomictry(天影)回复于 2006-03-02 15:25:38 得分 0
一个歪注意,能不能尝试得到系统工具-->>事件查看器 中信息,如果程序崩溃的话会在里面留下信息的。:)Top
6 楼oyljerry(【勇敢的心】→ ㊣提拉米苏√㊣)回复于 2006-03-03 11:40:53 得分 0
周期性发送确认信息~Top
7 楼Spacesoft(暗夜狂沙)回复于 2006-03-05 22:04:55 得分 0
呵呵,想一想你的问题的几个关键字,答案不就出来了吗?“非法操作”,“异常”,还有比调试器更合适做这个工作的吗?所以有一个比较帅的办法,就是写一个简单的调试器。
你可以这样做:
用守护进程来启动要监视的进程,注意CreateProcess 的时候dwCreationFlags要包含DEBUG_ONLY_THIS_PROCESS。我们就是利用Debug 信息来了解子进程是否出现了异常。
然后守护进程就一直调用WaitForDebugEvent函数,捕捉子进程的DebugEvent。当接到子进程的EXCEPTION_DEBUG_EVENT 事件的时候,说明子进程出现了异常,这个时候就可以将子进程结束,然后重启之了。Top
8 楼sboom(+-LingCh-+)(爱美人不爱VC)回复于 2006-03-06 00:13:35 得分 0
楼上强Top
9 楼somexing(somexing)回复于 2006-03-06 08:37:43 得分 0
直接发一个WM_QUIT消息关闭程序就是了,何必一定要关闭窗口Top




