判断窗体是否无响应(监控窗体) - 小众知识

判断窗体是否无响应(监控窗体)

2023-02-17 05:05:57 苏内容
  标签: 窗体
阅读:3258
一个窗体对应于一个线程,有时候模糊测试进行监控的时候,单独对进程进行监控可能无法达到相应的效果,因此需要对线程监控。
一种方式 是对该进程的所有线程进行监控,通过判断线程的状态来判断是否已经发生异常。但实际中用ProcessMoniter进行查看的时候,发现一个窗体停止响应,但是此线程依旧正常Running状态,猜测可能是延时或者其他原因到时实时反馈并不是正常。
 
注:python Win32api和win32gui中都没有相关的函数进行检测判断。
 
另一种方式是直接判断窗体是否正常响应。
一般是使用三种方式(这里说的窗体未响应是指窗体无法移动,并且在任务管理器中窗体状态是未响应),
 
1. 判断窗体名,一般在窗体停止响应的时候,会在窗体名上有额外的字符串”(未响应)“,那么直接通过GetWindowText,获取窗体的标题,因此来判断窗体是否正常了。
局限性:这个方式并不稳定,在后面的测试过程中,发现有时候窗体发生未响应,但是窗体上标题并不显示为未响应,或者有时会经过很长时间才出现”未响应“字符串。
 
2. 直接给窗体发消息,SendMessageTimeout函数,如果第一个返回值返回为0则表示无法窗体停止响应。
参考:
https://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k(SendMessageTimeout);k(DevLang-C);k(TargetOS-WINDOWS)&rd=true
但是在使用Python win32gui库中的 SendMessageTimeout的时候。在窗体无响应的时候,仍然返回为非0值。因此这种方式也不太实用。
 
3. 使用MS提供的库函数直接进行判断。
这些函数会和Windows的版本有关,不同版本使用不同的函数。
Win 9x为IsHungThread(比较老的系统了);在Win NT/2000中为IsHungAppWindow,我在Win7中使用的是IsHungAppWindow,能够正常检测。
 
IsHungAppWindow:官方描述是
The return value is TRUE if the window stops responding; otherwise, it is FALSE. Ghost windows always return TRUE.
这个就是直接用于判断window是否响应的函数。
通过测试,能够正常检测。
使用的是Python ctypes调用windows系统库。
 
no_response = ctypes.windll.user32.IsHungAppWindow(hwnd)

 


查了些资料,正在整理中。现在记录一下:

方法一:判断程序的线程是否Responding。

Process有此属性,获取了Process后直接判断Responding属性即可。


方法二:API方法 IsHungAppWindow

	#region 窗体是否挂起
        [DllImport("User32.dll", CharSet = CharSet.Auto)]        public static extern bool IsHungAppWindow(IntPtr hwnd);        #endregion


方法三:API 给程序发送消息 SendMessageTimeout

声明方法为:

public enum SendMessageTimeoutFlags : uint
        {
            SMTO_NORMAL = 0x0,
            SMTO_BLOCK = 0x1,
            WM_NULL = 0,
            SMTO_ABORTIFHUNG = 0x2,
            SMTO_NOTIMEOUTIFNOTHUNG = 0x8
        }
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessageTimeout(            IntPtr windowHandle,
            uint Msg,
            IntPtr wParam,
            IntPtr lParam,
            SendMessageTimeoutFlags flags,
            uint timeout,
            out uint result);


调用的方法:

public static bool IsExeNotResponse(IntPtr hwnd)
        {            var lRes = uint.MinValue;            //Register the message
            var lMsg = RegisterWindowMessage("WM_HTML_GETOBJECT");            //Get the object
            SendMessageTimeout(hwnd, lMsg, IntPtr.Zero, IntPtr.Zero, SendMessageTimeoutFlags.WM_NULL, 1000, out lRes);            return lRes == 0;
            
        }

 



 


扩展阅读
相关阅读
© CopyRight 2010-2021, PREDREAM.ORG, Inc.All Rights Reserved. 京ICP备13045924号-1