以下内容是我一周前发在VBGood论坛的讨论帖子,现搬过来,并做了修改及、补充排版等。 在VB 6.0中如何判断一个程序、进程、窗口出现假死、无响应、挂起、出错等现象。

    某个程序由于各种不确定因素经常崩溃出错。

出错症状如下:
    1.出错直接进程消失,无任何提示。
    2.弹出错误框“xx错误、xx内存不能为read”之类的不确定内容窗口。
    3.进程还在,但是程序什么反应都没有,已假死。。
    4.各种猎奇的错误……

现在要做、解决的是:

    循环监视该程序,当此程序出现以上症状的时候,执行一些操作,例如:重启该程序之类的。

    目前讨论如何判断该程序出现了以上症状?

解决方案:

    第一种、很简单,循环判断该程序进程还在没。

    第二种、可以遍历查找错误窗口,但是这个内容非固定的,是个问题。。。

    第三种、弹出错误框后,程序挂起,占用内存大小、CPU应该固定了不变了,可以通过这个判断?如果一段时间内,占用内存和CPU都没有变化,即判定已假死。但这个存在误判的问题,如果程序处于空闲状态,一段时间内占用内存和CPU也是不变化的。这是个问题,各位有没有什么好方法?

    第四种、未知。。。。

sunfrank 回帖道:

    用管道通讯(另一个程序不是自己写的就没办法了……)

acme_pjz 回帖道:

    第二种情况,可以在系统设置里面取消掉这个窗口(详见底下说明),让程序错误了就直接退出,这样就变成问题一了……

    第三种情况,好像有一个API可以解决:IsHungAppWindow

    API函数功能:判断一个进程出错或未响应,该API是微软没公开的API之一。

    API函数原形:Declare Function IsHungAppWindow Lib "user32.dll" (ByVal hWnd As Long) As Long

    API函数返回值:返回0代表无效句柄或没问题,返回1代表无响应。

我回帖道:

    昨天无意间想到一个办法,可以解决以上所有情况。

    这个程序不不是自己写的,无法改变功能(反汇编除外,不在本贴讨论范围之内),没错。但是我们可以注入一个dll进去,独立运行。

    每隔一段时间跟守护程序进行油槽通讯或其他方式的本地通讯。如果守护程序在指定时间内没收到指定信息,便判定程序已假死。然后执行相应的重启操作。

    目前不知道程序假死后,注入的dll线程还运行着没(等会儿试验下)。。。还有就是不知道对目标程序稳定性会造成影响不。

测试完后,我回帖道:

    我擦,程序崩溃后,子线程居然还在运行,完全不影响。除非进程完全退出了。。。

    另外弱弱的问一下,如何模拟“xx内存不能为read错误”?就是按个按钮后,出现这个错误(不是对话框模拟),用来调试注入的dll在这种情况下的反映。

    PS,刚才翻论坛帖子翻到了:

        一、错误报告:在“系统属性”->“高级”->“错误报告”->“禁用错误汇报,发生错误时不要通知我”才能看到“内存不能read”,要不然只能看到“遇到问题需要关闭”。

        二、如何让VB出现内存不能为read:
            http://www.vbgood.com/thread-79352-1-1.html
            http://www.vbgood.com/viewthread.php?tid=73436

    都是楼上前辈的帖子。

补充知识:

让VB出现内存错误、不能为Read、非法操作:

将以下语句加在“Option Explicit”之后,编译好运行后,点关闭窗口按钮,出错。

Implements IPicture

IsHungAppWindow 函数详解:

详见这里:VB判断某窗口是否出错、挂起、无响应,IsHungAppWindow 函数详解,使用实例