软件看门狗--别让你地程序无响应(使用未公开API函数IsHungAppWindow,知识点较全)

正文
一.概述
一些重要的程序,必须让它一直跑着;而且还要时时关心它的状态——不能让它出现死锁现象。当然,如果一个主程序会出现死锁,肯定是设计或者编程上的失误。我们首要做的事是,把这个Bug揪出来。但如果时间紧迫,这个Bug又“飘忽不定”,那么,我们还是先写一个软件“看门狗”,暂时应一下急吧。

“看门狗”的需求描述:“看门狗”的运行不出现界面窗口,具有一定的隐蔽性;定时判断目标进程是否运行在当前系统中,如果没有则启动目标进程;判断目标进程是否“没有响应”,如果是则终止目标进程;如果目标进程“没有响应”的次数超过一定的数量,则将计算机系统重启。

二.预备知识
首先要介绍两个主要的函数,能够判断目标进程是否“没有响应”。在User32.dll中(没有文档公开),Win2k/NT下的IsHungAppWindow和Win9X下的IsHungThread;前者是以一个窗口句柄作为参数,后者是以线程ID作为参数。我们可以通过VC开发工具的Depends查到这两个函数。
要使用这两个函数,我们必须先动态导入,如下:
if (m_hUser32 == NULL)
{
     m_hUser32 = GetModuleHandle("USER32.DLL");
}
if (m_hUser32)
{
     m_IsHungNT   = (HUNG_FUNNT) GetProcAddress(m_hUser32, "IsHungAppWindow");
     m_IsHung9X   = (HUNG_FUN9X) GetProcAddress(m_hUser32, "IsHungThread");
}
另外,还有如下知识点:
1.     如何让窗口隐藏(当然通过Windows任务管理器还是可以看到的)
在框架窗口类的PreCreateWindow中修改窗口风格,如下:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
     if( !CFrameWnd::PreCreateWindow(cs) )
         return FALSE;
     // TODO: Modify the Window class or styles here by modifying
     //   the CREATESTRUCT cs

cs.dwExStyle |= WS_EX_TOOLWINDOW;   // Make invisible in taskbar
     cs.style       = WS_POPUP;           // Hide the main window

return TRUE;
}
2.     如何让“看门狗”只运行一个进程
使用互斥量。在CWatchDogApp::InitInstance()中,执行如下代码:
bool CWatchDogApp::IsUniqueCopyInProc()
{
     m_Mutex = CreateMutex(NULL, TRUE, "System Watch Dog");
     if (GetLastError() == ERROR_ALREADY_EXISTS)
     {
         return false;
     }
     return true;
}
该函数如果返回false,说明已经有一个WatchDog进程在运行了,当前进程就没有必要再执行下去了。在InitInstance如下处理:
if (!IsUniqueCopyInProc())
return FALSE;
3.     如何判断当前操作系统类型
bool CWatchDogApp::IsWinNT()

     OSVERSIONINFO OSVersionInfo;
     OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
     GetVersionEx(&OSVersionInfo); 
     if (OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
     {
         return true;
     }
     return false;
}
4.     如何自动重启计算机
在Win9x和Win2k/NT下,重启计算机的处理略有不同:
if (theApp.IsWinNT())
{
     // 在Win NT/2000下赋予关闭系统的权限
     static HANDLE hToken;
     static TOKEN_PRIVILEGES tp;
     static LUID luid;
::OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken ) ;
     ::LookupPrivilegeValue( NULL, SE_SHUTDOWN_NAME, &luid );
     tp.PrivilegeCount            = 1;
     tp.Privileges[0].Luid        = luid;
     tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
     ::AdjustTokenPrivileges( hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL );
     return ::ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0);
}
else
{
     return ::ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0);
}
5.     如何启动、结束其他进程
启动进程用CreateProcess,终止进程用TerminateProcess。参考代码如下:
bool CWatchDogView::RunTheSysProc()
{
     char     szPath[MAX_PATH];
     GetModuleFileName(NULL, szPath, MAX_PATH);
     CString strPath = szPath;
     strPath = strPath.Left(strPath.ReverseFind(‘//‘)) + "//HungDemo.exe";

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

if (!::CreateProcess(
         (LPCTSTR) strPath,
         NULL,
         NULL,
         NULL,
         FALSE,
         NORMAL_PRIOR99vY_CLASS,
         NULL,
         NULL,
         &StartInfo,
         &procStruct))
         return false;
     return true;
}
需要提醒的是,TerminateProcess是在万不得已的情况下使用的,它不会进入进程使用的DLL的入口点通知“脱离”(Detaching)状态。有时候,这样做是很危险的(DLL内部的全局数据可能受影响较大)。
6.     如何让Win2k/NT自动登录
修改注册表。在HKEY_LOCAL_MACHINE目录下的Software/Microsoft/Windows NT/ CurrentVersion/WinLogon下的AutoAdminLogon(字符串型)设置成1,并在DefaultUserName设置默认登录用户,DefaultPassword设置默认用户的密码。
7.     如何让Win2k/NT登录成功后直接执行你的程序(而不是默认的文件浏览器)
修改注册表。在注册表HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/ CurrentVersion/Winlogon/Shell的值从原先的explorer.exe修改为自己程序的绝对路径。

三.功能演示(Win2k/NT下)
友情提醒:开始演示之前,请先将你目前的工作保存。运行“看门狗”WatchDog;同时使用Ctrl+Alt+Del打开“Windows任务管理器”。稍候片刻,可以看到目标程序HungDemo会被启动(这个程序模拟了“没有响应”)。然后,WatchDog发现这个程序“没有响应”,则把它杀掉,然后重新启动一个新的HungDemo进程。如此的处理重复六次以后,系统会自动重启。

http://blog.csdn.net/jiangxinyu/article/details/5217909

时间: 2024-10-28 15:22:15

软件看门狗--别让你地程序无响应(使用未公开API函数IsHungAppWindow,知识点较全)的相关文章

关于实现一个软件看门狗的计划

由于是软件看门狗,因此他的角色只能算是个辅助工具. 尽管如此,他的功能应该还是有点意义. 此软件的实现计划如下: 1. 软件形式 一个模块soft_wdt.ko,运行在内核中. 2. 软件启动方法 insmod  soft_wdt.ko  dev=/dev/soft_wdt   timeout=5   log=/path/to/log.txt 几个参数分别是:要暴露给用户的设备文件,喂狗时间间隔,日志文件路径 未来可能会支持更多的参数 3. 服务对象 一个个独立的用户态线程. 4. 使用方法 哪

Linux 软件看门狗 watchdog —— 开门放狗、定期喂狗、狗咬人了

Linux 自带了一个 watchdog 的实现,用于监视系统的运行,包括一个内核 watchdog module 和一个用户空间的 watchdog 程序. 内核 watchdog 模块通过 /dev/watchdog 这个字符设备与用户空间通信.用户空间程序一旦打开 /dev/watchdog 设备(俗称“开门放狗”),就会导致在内核中启动一个1分钟的定时器(系统默认时间),此后,用户空间程序需要保证在1分钟之内向这个设备写入数据(俗称“定期喂狗”),每次写操作会导致重新设定定时器.如果用户

bash脚本之软件看门狗示例

#!/bin/sh # file timestamp to record the heartbeat of spring-rest-server timestamp=/usr/apache-tomcat-7.0.42/logs/timestamp.log # timeout 60s timeout=60000 # error log stderr=/usr/apache-tomcat-7.0.42/logs/tomcat-watchdog.log # 1 means need to restar

Linux 软件看门狗 watchdog

Linux 自带了一个 watchdog 的实现,用于监视系统的运行,包括一个内核 watchdog module 和一个用户空间的 watchdog 程序.内核 watchdog 模块通过 /dev/watchdog 这个字符设备与用户空间通信.用户空间程序一旦打开 /dev/watchdog 设备(俗称"开门放狗"),就会导致在内核中启动一个1分钟的定时器(系统默认时间),此后,用户空间程序需要保证在1分钟之内向这个设备写入数据(俗称"定期喂狗"),每次写操作会

Linux 软件看门狗 watchdog 喂狗

Linux 自带了一个 watchdog 的实现,用于监视系统的运行,包括一个内核 watchdog module 和一个用户空间的 watchdog程序.内核 watchdog 模块通过 /dev/watchdog 这个字符设备与用户空间通信.用户空间程序一旦打开 /dev/watchdog 设备(俗称"开门放狗"),就会导致在内核中启动一个1分钟的定时器(系统默认时间),此后,用户空间程序需要保证在1分钟之内向这个设备写入数据(俗称"定期喂狗"),每次写操作会导

android:程序无响应,你该如何定位问题?

如果MainThread长时间无响应,系统会提示"XXX无响应",然后用户会关闭.那么,如何定位问题呢?无响应并不像Crash,它抓取不到异常日志,通常我们需要调试,才能定位问题.如何调试呢? 1.在Eclipse Devices窗口,选中app对应的包名,然后点击debug图标(绿色的小虫子),然后切换到Debug视图 2.切换视图之后,可以看到debug下,app的线程列表 3.对于main线程(第一个线程),选中,并将其挂起Suspend 4.然后我们就可以看到,Suspend之

转 -android:程序无响应,你该如何定位问题?

如果MainThread长时间无响应,系统会提示“XXX无响应”,然后用户会关闭.那么,如何定位问题呢?无响应并不像Crash,它抓取不到异常日志,通常我们需要调试,才能定位问题.如何调试呢? 1.在Eclipse Devices窗口,选中app对应的包名,然后点击debug图标(绿色的小虫子),然后切换到Debug视图 2.切换视图之后,可以看到debug下,app的线程列表 3.对于main线程(第一个线程),选中,并将其挂起Suspend 4.然后我们就可以看到,Suspend之后,mai

ANR程序无响应原因及应对办法

Android ANR 分析解决方法 一:什么是ANR ANR:Application Not Responding,即应用无响应 二:ANR的类型 ANR一般有三种类型: 1. KeyDispatchTimeout(5 seconds) --主要类型按键或触摸事件在特定时间内无响应 2. BroadcastTimeout(10 seconds) --BroadcastReceiver在特定时间内无法处理完成 3. ServiceTimeout(20 seconds) --小概率类型 Servi

打客服、重装系统都无解,苹果mac电脑各种程序无响应的最终解决办法

最近系统 变得异常难用 qq登陆就卡死.网易云音乐进不去.酷狗卡死.ios模拟器卡死...... 各种变态卡死 查遍网络.打客服.清缓存.重装系统依然无解????? 半个月了,真折磨 就要我放弃mac的时候,我查看了性能监视器,发现卡死的程序都是需要高性能GPU,就是显卡, 这下我怀疑时显卡没有切换,打开节能器,果然没有一直打开,系统又没有智能到自己打卡 把节能器锁定选项去掉,立马各种程序成功使用, qq亮了.网易云音乐响了.xcode的模拟器可以调试了 妈的..真心不喜欢苹果了,app提交六次