Jump to content

Full-Screen Crash Recovery 1.0


Ascend4nt
 Share

Recommended Posts

Full-Screen Crash Recovery 1.0

Crashed programs or games with screens that won't go away? Ctrl-Alt-Del, Alt-F4, Alt-Tab, and the Windows Key not working for ya? Do you find that you can 'almost' just get out of a game screen, but see constant flicker and only parts of the Windows desktop or mouse pointer?

Want a fix for all that crap? Here it is. This bad boy will drop that program and kick it to the curb. public/style_emoticons/autoit/laugh.gif =P

So what's it all about? This program uses Yashied's 'HotKey.au3' UDF to track keypresses and looks for this combo:

Shift-Alt-Del (easy enough to remember eh?)

Once you press that combo, my program will kick in and start analyzing the Windows on the screen - finding at most two windows that have full-screen or maximized status (there is a difference in Window's world). If the *active* window is the one that matches those criteria, it is chosen as the 'target' (otherwise, the first found non-Explorer window will be the target).

Now, I'm all about safety (preventing accidents) - but I'm also all about killing something if it's really crashed.

So what my program does on each hotkey press is this:

  • On the 1st Shift-Alt-Del press, the program determines if the 'target' Window it finds is Hung/Crashed using a quick method. If Window reports that it is - it's killed on the spot, and the cycle resets. If not, it will save the 'target' info for the proceeding hotkey presses.
  • On the 2nd Shit-Alt-Del press, the program will look again through the Window list. If it finds the same 'target', it will again check if the program is Hung/Crashed or Suspended (if so, kill & reset). This process can take up to 5 seconds, especially for a suspended app. Now, since the app was found twice, and is responding to messages, my program will attempt to alter a window's 'Always-on-Top' status and Minimize it. Sometimes (!!) this may solve the case (other times, not-so-much).
  • On the 3rd Shift-Alt-Del press, the program will search again as above, compare the window to the last one, and if it's the same, and still in full-screen/maximized state, it will finally say 'screw it', and just terminate the application.
At each step, you'll get a speaker Beep confirmation (if you don't have an internal PC speaker, you can alter the Beeps to 'SoundPlay()' or somesuch). In any case, the Beeps are like this. (thanks montymintypie for suggesting this):

  • low beep = no window found in maximized/full-screen status
  • high beep = window found, but Windows isn't reporting it is hung
  • dual-tone beeps (mid-then-high) = Window terminated.
In addition, if the hotkey to close the app down is pressed, you'll get a reverse dual-tone-beep (high-low) meaning its shut down. By the way, that hotkey is:

Shift-ALT-Q (terminate my program)

The reason for this 'third-times-a-charm' thinking is that:

  • You want to be sure that you really wanted to close that app (if for some reason Windows reports the app as crashed though, there's no 2nd or 3rd time),
  • Sometimes minimizing actually does work, and
  • If you were able to close/minimize the application, and switched to another and maximized/full-screened it, the code will recognize that the screen is no longer in that maximized/full-screen state, and simply reset its internal variables (and the HotKey-press count will reset to 0)
NOTES:

  • Any window owned by Explorer.exe process will be IGNORED, with the exception that if explorer.exe itself has crashed (and pulled other windows into its vortex), it will allow it to be terminated (and then restarted). But under typical circumstances, it will differentiate the Explorer Windows from regular Application/Game windows, and by doing so, prevent accidental closure of the main Windows interface!
  • As stated above, any time the same app is not found to be minimized, it will reset the internal count and variables, so the HotKey-press count will reset to 0.
Get it now at http://sites.google.com/site/ascend4ntscode/fullscreencrashrecovery

A list of the major enhancements/changes since I started (prior to v. 1.0!):

  • Added two methods for detecting if an application is hung/crashed/suspended
  • Rewrote a LOT of the code based on my own experiences with crashes (both in XP and Vista, applications and games)
  • Separated functions to make it easier to understand and centralized Debug messages in case you'd like to output them to a log.
  • Rewrote the main function AGAIN, due to certain Win..() functions in AutoIT failing to work on crashed applications

    (I've remarked about these functions and my experiences with them in the source code right under the header)

  • Added better 'beep-notifications' (thanks to montymintypie for getting me to do that)
Ascend4nt's Program License agreement:

While I provide this program freely, if you do distribute the program, the only requirements I have are:

  • I (Ascend4nt) must be Acknowledged as the author
  • The License agreement document (in the ZIP file) must be kept bundled together with the code.
  • A link must be provided to the page containing the program (linked above)
  • Do *not* under any circumstances 'reverse-engineer' the code - in other words, do not pull out the source code. I may distribute the source code in the future - but if you have or find an old copy of my code, do not distribute it without my consent, which must be obtained through the 'ContactMe' page on this site.
Edited by Ascend4nt
Link to comment
Share on other sites

That API "IsHungAppWindow" is a great find! (I like your implementation too!)

I've been using "SendMessageTimeout" to find out if the messagehandler is stuck, app is locked...

Think I'll have to try your function out instead! :D

/Manko

Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...
Link to comment
Share on other sites

2. On the 2nd Shit-Alt-Del press, the program will look again for the full screen/maximized window (starting with the Active one), and see if it's the same as the one found on the 1st HotKey-press. If yes, the program sends a 'Minimize Window' command to the window. Sometimes this may solve the case, other times note.

I must admit, that is the best typo i've seen all day! Nice script tho! i will use it!

Visit my website to see all my finished releases!Releases here:UDFs:GUI ResizingColor List (Web Colors)GUIFade_NearestPower

Link to comment
Share on other sites

That API "IsHungAppWindow" is a great find! (I like your implementation too!)

I've been using "SendMessageTimeout" to find out if the messagehandler is stuck, app is locked...

Think I'll have to try your function out instead! :D

/Manko

Manko, your method is probably the preferred way, as MSDN says the 'IsHungAppWindow' API call 'might be altered or unavailable in subsequent versions of Windows'. But hey, they say that for a number of functions don't they? And I say that MSDN should be held responsible for supporting the functions they put up documentation for, darnit! But hey - you're method might be more 'recommended', and I didn't even think to look for alternatives until I looked at the documentation for what you mentioned hehe.

Either way, like I said in my testing - it has never reported an App as hung. I'd like to know if it actually ever does!

Link to comment
Share on other sites

Updated the program:

*EDIT: changed the behavior slightly - if the DLLCall fails, it doesn't just beep and return immediately - it now continues on to check the '$iAttemptedKillCount' variable (and work as reported above). The change was made just in case the DLLCall consistently fails.

Btw, thx insignia96 (for both the compliment and the typo spot! hehe)

Link to comment
Share on other sites

Either way, like I said in my testing - it has never reported an App as hung. I'd like to know if it actually ever does!

It should be easy to test. If you have a graphical autoit using only GUIGetMsg method for its messagehandling...

...instead of handling incomeing messages and quickly calling it again, put an endless loop in... :D

...or just use my app to suspend some grahical app, test it with your function, and u should get results. :D

/Manko

Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...
Link to comment
Share on other sites

It should be easy to test. If you have a graphical autoit using only GUIGetMsg method for its messagehandling...

...instead of handling incomeing messages and quickly calling it again, put an endless loop in... :D

...or just use my app to suspend some grahical app, test it with your function, and u should get results. :D

/Manko

Unfortunately, creating a graphical AutoIT program like you said still responds to messages, even with SendMessageTimeOut. I've even disabled the minimize/maximize boxes and did all sorts of wonky things, but to no avail!

I did happen to use your great ProDLLer app, as well as Advanced Process Termination to 'Suspend' apps. By doing this, I found out that I had to do a lot of rewriting!

Turns out that WinGetTitle() and WinSetState() (@SW_MINIMIZE) on a suspended app will cause my program to just sit there waiting for those functions to return (which they won't, until the application is finally unsuspended).

Oh, and 'IsHungAppWindow' always returned False - though I don't know if there's a distinction between a 'hung' application and a 'suspended' one. I *still* need to find a program running full-screen that crashes so that I can find out for certain! I think I know of one person who has a crash at a specific point in time in some game.. I'll need to go over someday and try my program out.

So anyway, I'll be posting new code shortly that should solve every conceivable problem ;)

Link to comment
Share on other sites

New update:

*EDIT 2: rewrite of much of the code. No longer locks up for 'Suspended' applications, and also now attempts a 2nd method of detecting if an app has crashed (Note: this will take about 5 seconds if the given app truly isn't responsive, but will definitely terminate it [2nd method happens on 2nd Hotkey-press]). Also a little more debug info is written to the console (you can disable these calls if you like).

Link to comment
Share on other sites

I'm in OS X at the moment, so I can't test this.

Sometimes TF2 or Gmod will crash, and if I do Ctrl-Alt-Del the mouse cursor will change as I roll over parts of the Task Manager window, but I can still only see the crashed game window, with a freeze frame of the last rendered game frame. This helps with this, right? So, if I encounter this, I press the shortcut a few times until it quits? Because that sounds like a REALLY good idea. I'll download this and see how it goes next time I run a game. If it works, it's definitely going in my start-up items. :-D

Will T

Link to comment
Share on other sites

montymintypie,

That's EXACTLY the type of situation I made this for! (only, after making it, I forgot what friggin programs & games were doing that to me! haha :D ) So yes, please please test it! :D And if you can do me a favor, let me know what the debug output is (run it through Scite, or I can give u a simple output-redirector program I wrote so we can gather the output)

A couple of reminders - between Shift-Alt-Delete presses, you must release ALL three keys before pressing them again. And just hold it for like 2/10ths of a second (due to the sleep in the loop). Oh, and make sure the _AsyncHotKeySet UDF is in the same folder (or just paste it all at the beginning of the script if you're just experimenting).

(I may consider putting this all in a zip since I'm starting to realize how big a pain it would be for people to grab all the code I do #include's on, and paste them into scripts..)

Link to comment
Share on other sites

I've been busy recently, haven't been playing many games, so I might not be able to give results too soon...

I've set it so scripts open in SciTe by default, so it'll open in there anyway. :D

If this thread is old enough to be 'dead' by the time a game crashes for me, I'll just PM you.

Will

Link to comment
Share on other sites

Inverted,

Overkill? No, but I'd have to say that I'd never assign those type of macros to mouse or joystick buttons, all without checking if the application isn't hung.

In addition:

  • What if you accidentally press the button? Oops, I killed the game that was working fine? (or, woopsie,I accidentally rebooted and killed everything?!) That seems like going a bit too far to me :D
  • What if the crashed game/app isn't the active window? (this happens sometimes if you actually switch windows (for example, using Ctrl-Alt-Del or Alt-Tab). You could actually wind up closing Windows explorer by accident. (The applications that I've come across that crash badly typically don't let you even *see* the other screen, let alone know what the 'active' window is if you tried to switch)
  • And in addition to that - WinGetProcess ("[active]") returns a seemingly random # for programs that are suspended (just tested), while WinGetHandle("[ACTIVE]") returns 0. I'm *guessing* these results might be the same for crashed apps - so in effect you'd be closing an invalid or incorrect process. Not a good move..

(*edit: just tested WinGetProcess ("[active]") on suspended apps, so adjusted 3rd point to reflect that)

Edited by ascendant
Link to comment
Share on other sites

I still play Renegade on occasion, and it will lock up in a manner that only a cold boot will help the situation. This is quite annoying as I have to wait for the computer to boot to get back into the game. Will be trying this script on my desktop at the house.

Thanks,

Jarvis

AutoIt Links

File-String Hash Plugin Updated! 04-02-2008 Plugins have been discontinued. I just found out.

ComputerGetInfo UDF's Updated! 11-23-2006

External Links

Vortex Revolutions Engineer / Inventor (Web, Desktop, and Mobile Applications, Hardware Gizmos, Consulting, and more)

Link to comment
Share on other sites

New version:

*EDIT 3: modified to work with HotKey.au3, also modified one of the DLLCall @error checks

@JSThePatriot: Any feedback on how well it works (along with the log info if you run it from Scite) would be much appreciated :)

Link to comment
Share on other sites

I haven't had a crash yet... I'll keep you posted.

Jarvis

AutoIt Links

File-String Hash Plugin Updated! 04-02-2008 Plugins have been discontinued. I just found out.

ComputerGetInfo UDF's Updated! 11-23-2006

External Links

Vortex Revolutions Engineer / Inventor (Web, Desktop, and Mobile Applications, Hardware Gizmos, Consulting, and more)

Link to comment
Share on other sites

I tried to test using the Gmod loading screen, as it seems frozen (but is just loading). Instead, it successfully minimised the window. Actually a good thing! Here's the console output:

Found window matching criteria, Maximized status=False, Alternative Full-Screen test result=True...
Checking if window 'Garry's Mod' (process ID #5792) is 'hung'...
SendMessageTimeoutW (WM_GETTEXT msg) return succeeded, text return = 'Garry's Mod'
2nd attempted Kill command received. Sent 'Minimize-window' command to window..

Also, I'm using my Mac in BootCamp, and I don't hear a beep. Any other way to give me audio confirmation?

This is the first time I've wanted a game to crash... :)

Will

Link to comment
Share on other sites

montymintypie,

a Mac? How the heck are you running the program? A virtual machine? And what's BootCamp?

You could probably replace Beep() with SoundPlay(), assuming you have a sound to play, and it works on whatever weird config you have :)

Link to comment
Share on other sites

montymintypie,

a Mac? How the heck are you running the program? A virtual machine? And what's BootCamp?

You could probably replace Beep() with SoundPlay(), assuming you have a sound to play, and it works on whatever weird config you have :)

BootCamp basically means I boot in Windows instead of Mac. It's just like having a PC. Great for games!

I used Audacity to replicate the beeps, then saved them as wavs and used the SoundPlay() function. It's good to know if the program is doing something! Still haven't crashed a game yet...

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...