Jump to content


Photo

[How To] detect a Hung Window


  • Please log in to reply
5 replies to this topic

#1 SKAN

SKAN
  • Administrators
  • 9062 posts

Posted 14 October 2006 - 08:40 PM

How to detect a Hung Window ?
http://www.autohotke...p?p=83784#83784

I wanted to write a script that monitors all the visible windows (for responsiveness) and found that a DllCall to "User32.dll\SendMessageTimeout" does the job.

MSDN Reference: SendMessageTimeout Function


LRESULT SendMessageTimeout( HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam,
UINT fuFlags,
UINT uTimeout,
PDWORD_PTR lpdwResult
);
When the above is translated in AHK to our needs, it becomes:

DllCall( "SendMessageTimeout"
           , UInt, ID   ; ID will be the handle to the target Window ( ahk_id )
           , UInt, 0x00 ; WM_NULL ( the safest message parameter in this case )
           , Int , 0    ; wParam - not required
           , Int , 0    ; lParam - not required
           , UInt, 0x08 ; SMTO_NOTIMEOUTIFNOTHUNG 
           , Int , 3    ; Timeout in seconds
           , "UInt *"   
           , Result )   ; Result is the variable that contains the result

I tried different combinations .. The above works well when I wanted to monitor multiple windows.

The difference between SendMessage and PostMessage:

The SendMessage function sends the specified message to a window or windows. The function calls the window procedure for the specified window and does not return until the window procedure has processed the message. The PostMessage function, in contrast, posts a message to a thread’s message queue and returns immediately.

What about SendMessageTimeout?:

The SendMessageTimeout function sends the specified message to a window or windows. The function calls the window procedure for the specified window and, if the specified window belongs to a different thread, does not return until the window procedure has processed the message or the specified time-out period has elapsed. If the window receiving the message belongs to the same queue as the current thread, the window procedure is called directly the time-out value is ignored.

What is the Trick?

When we send a WM_NULL ( 0x00 ) as a message to a window it processes it, and since it has to do nothing returns back the 0x00. However, a "Hung window" will not respond back and so SendMessageTimeout will timeout resulting in a non-zero value in the variable Result.

Any limitations?

A Window might become unresponsive during its startup. SendMessageTimeout (with the example parameters) will see it. This might/might not be the desired effect when monitoring multiple windows. But in case of monitoring a single window, one has the choice to experiment with the fuFlags parameter. There is scope for lot more experimentation with this User32.dll function.

Here is a short version of my script which continuously monitors for window responsiveness (all non-hidden windows).


Disclaimer: The below is just an experiment and I have not tested it well! There is an alternative for > Win2000 : user32.dll/IsHungAppWindow - See MSDN Reference : IsHungAppWindow


#Persistent
Menu, Tray, Icon, User32.dll, 2
SMTO_NOTIMEOUTIFNOTHUNG := 8      
Delay = 200                    
SetTimer, CheckAllWindows, 10
Return

CheckAllWindows:
  SetTimer, CheckAllWindows, Off
  WinGet, hWnd, List

  Loop, %hWnd%           {

        ID := hwnd%A_Index%

        DllCall("SendMessageTimeout", UInt,ID, UInt, 0, Int,0, Int,0
                , UInt, SMTO_NOTIMEOUTIFNOTHUNG, Int,3, "UInt *", Result )

        WinGetTitle, Title, ahk_id %ID%
        IfNotEqual,Result,0, GoSub,Alert

        Sleep %Delay%
                         }
  SetTimer, CheckAllWindows, %Delay%
Return

Alert: ; This routine can be used to repeat testing & offer a WinKill.
MsgBox,64,Alert: Window probably hung?!, Window Title: %Title%, 3
Return

So you have copy / pasted the above code and want to test it. Do you have to wait until a Window really hangs?
I ran it from the startup and waited for three days and only today it gave me a notification when an app was opening a huge text file.. ( Ofcourse that was momentary unresponsiveness, but enough proof for me ).

In fact I wanted to post a request in Ask-for-help titled: How to simulate a hung window ? :D

Lucky I was, to find a simple way: HungGUI.ahk simulates a hung window for testing the above code.. and below is the snapshot of the code :?: Posted ImageHungGUI.ahk plays a foul game by returning -1 for the WM_NULL message it recieves. That does the good for our testing! 8)

Regards, :)



#2 Chris

Chris
  • Administrators
  • 10727 posts

Posted 15 October 2006 - 12:03 AM

Nice post.

It might be of interest that AutoHotkey calls IsHungAppWindow() internally to avoid operating upon hung windows. However, it's not foolproof because sometimes the OS doesn't detect that a window is hung until it's too late and the script has already tried to do something to it (which can cause the script to hang too).

#3 SKAN

SKAN
  • Administrators
  • 9062 posts

Posted 15 October 2006 - 09:39 AM

Nice post.


Thanks! :)

It might be of interest that AutoHotkey calls IsHungAppWindow() internally to avoid operating upon hung windows. However, it's not foolproof because sometimes the OS doesn't detect that a window is hung until it's too late and the script has already tried to do something to it (which can cause the script to hang too).


Oh! When I was tying to simulate a hung window, many times the monitoring script got hung up instead. :shock: :D

I am still waiting for a real hung window to see whether the monitor is able to see it and WinKill it!

Regards, :)

#4 Rajat

Rajat
  • Members
  • 1886 posts

Posted 15 October 2006 - 12:46 PM

thanks Suresh! i can already think of a couple of uses for this! :)

#5 edwardadams

edwardadams
  • Members
  • 1 posts

Posted 04 June 2012 - 02:47 PM

Thanks for your posting, it is very much helpful. =) Try also to follow this link..<!-- m -->http://blogs.msdn.co... ... art-2.aspx<!-- m -->
I hope it is useful.

#6 Guests

  • Guests

Posted 08 August 2012 - 01:14 PM

Can this method be extended to detect a hung process?