Jump to content
Sign in to follow this  
argumentum

on "AutoIt Error" - please help with fastest way to close it.

Recommended Posts

#NoTrayIcon

If @Compiled Then Exit MsgBox(262144, @ScriptName, "run this test from SciTE" & @CR & "this is just a test", 5)

#include <WinAPI.au3> ; for _WinAPI_FindWindow
#include <Misc.au3> ; for _IsPressed

If StringInStr($CmdLineRaw, "DoACrash") Then DoACrash()
Func DoACrash()
    Local $a = "caca"
    $a[1] = "more caca"
EndFunc   ;==>DoACrash

Run('"' & @AutoItExe & '" "' & @ScriptFullPath & '" DoACrash') ; to create the initial crash

catchTheCrash()
Func catchTheCrash()
    AutoItWinSetTitle("if this window not found, then, a crash catcher is wanted ???")
    Local $hDLL = DllOpen("user32.dll")
    Local $w, $t = TimerInit()
    While 1
        ToolTip("press and hold ""ESC"" to exit." & @CR & "loop time: " & Round(TimerDiff($t)) & " mSec.")
        $t = TimerInit()
        Sleep(20)
        If _IsPressed("1B", $hDLL) Then Exit 0 ; ESC key
        $w = _WinAPI_FindWindow("#32770", "AutoIt Error") ; very fast, does not affect CPU much
        If $w Then
            WinSetState($w, "", @SW_HIDE) ; all these are slow. Is there a faster way to not show the MsgBox ?
            ConsoleWrite("--- " & @MIN & ":" & @SEC & "." & @MSEC & @CRLF & _
                    ControlGetText("AutoIt Error", "", "Static2") & @CRLF)
            WinClose($w)
            Run('"' & @AutoItExe & '" "' & @ScriptFullPath & '" DoACrash') ; ..to keep on crashing ;)
        EndIf
    WEnd
EndFunc   ;==>catchTheCrash

is there a faster way to get the info. and close the MsgBox ?

Edited by argumentum

Share this post


Link to post
Share on other sites

Hello. Probably something like this could work.

 

#NoTrayIcon
#include <APISysConstants.au3>
#include <GUIMenu.au3>
#include <WinAPIProc.au3>
#include <WinAPISys.au3>
#include <WindowsConstants.au3>


#Region Globals
Global $hEventProc = 0
Global $hEventHook = 0
#EndRegion Globals




If @Compiled Then Exit MsgBox(262144, @ScriptName, "run this test from SciTE" & @CR & "this is just a test", 5)

#include <WinAPI.au3>; for _WinAPI_FindWindow
#include <Misc.au3>; for _IsPressed

If StringInStr($CmdLineRaw, "DoACrash") Then DoACrash()



Func DoACrash()
    Local $a = "caca"
    $a[1] = "more caca"
EndFunc   ;==>DoACrash

_RegisterAutoitMsgErrorHandler()

Run('"' & @AutoItExe & '" "' & @ScriptFullPath & '" DoACrash') ; to create the initial crash

catchTheCrash()

Func catchTheCrash()
    AutoItWinSetTitle("if this window not found, then, a crash catcher is wanted ???")
    Local $hDLL = DllOpen("user32.dll")
    Local $w, $t = TimerInit()
    While 1
        ToolTip("press and hold ""ESC"" to exit." & @CR & "loop time: " & Round(TimerDiff($t)) & " mSec.")
        $t = TimerInit()
        Sleep(20)
        If _IsPressed("1B", $hDLL) Then Exit 0 ; ESC key
        $w = _WinAPI_FindWindow("#32770", "AutoIt Error") ; very fast, does not affect CPU much
        If $w Then
;~          WinSetState($w, "", @SW_HIDE) ; all these are slow. Is there a faster way to not show the MsgBox ?
;~          ConsoleWrite("--- " & @MIN & ":" & @SEC & "." & @MSEC & @CRLF & _
;~                  ControlGetText("AutoIt Error", "", "Static2") & @CRLF)
;~          WinClose($w)
            Run('"' & @AutoItExe & '" "' & @ScriptFullPath & '" DoACrash') ; ..to keep on crashing ;)
        EndIf
    WEnd
EndFunc   ;==>catchTheCrash



Func _RegisterAutoitMsgErrorHandler()

    If $hEventProc Or $hEventProc Then
        _FreeHandles()
    EndIf

    $hEventProc = DllCallbackRegister('_EventProc', 'none', 'ptr;dword;hwnd;long;long;dword;dword')
    If $hEventProc = 0 Then Return False
    $iRegistered = OnAutoItExitRegister('_FreeHandles')
    If $iRegistered = 0 Then Return False
    $hEventHook = _WinAPI_SetWinEventHook($EVENT_SYSTEM_ALERT, $EVENT_SYSTEM_ALERT, DllCallbackGetPtr($hEventProc))
    If $hEventHook = 0 Then Return False
    Return True
EndFunc   ;==>_RegisterAutoitMsgErrorHandler



Func _FreeHandles()
    If $hEventHook Then _WinAPI_UnhookWinEvent($hEventHook)
    If $hEventProc Then DllCallbackFree($hEventProc)
    $hEventHook = 0
    $hEventProc = 0
EndFunc   ;==>_FreeHandles

Func _EventProc($hEventHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iThreadId, $iEventTime)
    #forceref $hEventHook, $iObjectID, $iChildID, $iThreadId, $iEventTime
    Local $iPID = ""
    Local Const $sAutoit = "Autoit"
    Local $sWinTitle = ""
    Local $sError = ""
    $sWinTitle = WinGetTitle($hWnd)
    _WinAPI_GetWindowThreadProcessId($hWnd, $iPID)
    If StringInStr($sWinTitle, $sAutoit) Then
;~      WinSetState($hWnd,"",@SW_HIDE)
        $sError = ControlGetText($hWnd, "", "Static2")
        ConsoleWrite("PID: " & $iPID & @TAB & "Error: " & $sError  &  @CRLF)
        ProcessClose($iPID)
    EndIf

EndFunc   ;==>_EventProc

Saludos

Share this post


Link to post
Share on other sites

@Danyfirex, just beautiful :) 
I did change the "Func _EventProc()" a bit. It catches and disappears the window in a single digit mSec. :lmao:

#NoTrayIcon

If @Compiled Then Exit MsgBox(262144, @ScriptName, "run this test from SciTE" & @CR & "this is just a test", 5)

If StringInStr($CmdLineRaw, "DoACrash") Then DoACrash()

#include <WinAPISys.au3>
#include <Misc.au3> ; for _IsPressed

#Region Globals
Global $hEventProc = 0
Global $hEventHook = 0
#EndRegion Globals


Func DoACrash()
    OnAutoItExitRegister("onExitForDoACrash")
    Local $a = "caca"
    $a[1] = "more caca"
EndFunc   ;==>DoACrash
Func onExitForDoACrash() ; added this to test OnAutoItExitRegister()
    FileWriteLine(@ScriptFullPath & '.log.txt', @AutoItPID & ' on EXIT' & @CRLF)
    Exit 5
EndFunc   ;==>onExitForDoACrash

_RegisterAutoitMsgErrorHandler()

Run('"' & @AutoItExe & '" "' & @ScriptFullPath & '" DoACrash') ; to create the initial crash

catchTheCrash()

Func catchTheCrash()
    AutoItWinSetTitle("if this window not found, then, a crash catcher is wanted ???")
    Local $hDLL = DllOpen("user32.dll")
    Local $t = TimerInit()
    While 1
        Sleep(1000)
        Run('"' & @AutoItExe & '" "' & @ScriptFullPath & '" DoACrash') ; to create the next crash
        ToolTip("press and hold ""ESC"" to exit.")
        If _IsPressed("1B", $hDLL) Then Exit 0 ; ESC key ; this way it makes sure to always work
    WEnd
EndFunc   ;==>catchTheCrash

Func _RegisterAutoitMsgErrorHandler()

    If $hEventProc Or $hEventProc Then
        _FreeHandles()
    EndIf

    $hEventProc = DllCallbackRegister('_EventProc', 'none', 'ptr;dword;hwnd;long;long;dword;dword')
    If $hEventProc = 0 Then Return False
    $iRegistered = OnAutoItExitRegister('_FreeHandles')
    If $iRegistered = 0 Then Return False
    $hEventHook = _WinAPI_SetWinEventHook($EVENT_SYSTEM_ALERT, $EVENT_SYSTEM_ALERT, DllCallbackGetPtr($hEventProc))
    If $hEventHook = 0 Then Return False
    Return True
EndFunc   ;==>_RegisterAutoitMsgErrorHandler

Func _FreeHandles()
    If $hEventHook Then _WinAPI_UnhookWinEvent($hEventHook)
    If $hEventProc Then DllCallbackFree($hEventProc)
    $hEventHook = 0
    $hEventProc = 0
EndFunc   ;==>_FreeHandles

Func _EventProc($hEventHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iThreadId, $iEventTime)
    #forceref $hEventHook, $iObjectID, $iChildID, $iThreadId, $iEventTime
    Local $t = TimerInit()
    If _WinAPI_FindWindow("#32770", "AutoIt Error") = $hWnd Then
        _WinAPI_SetWindowPos($hWnd, $HWND_BOTTOM, 0, 0, 0, 0, $SWP_HIDEWINDOW) ; way faster than WinSetState
        ConsoleWrite('--- took ' & Round(TimerDiff($t)) & ' mSec. to find and hide the window' & @CRLF)
        Local $iCount = 0, $sError = ControlGetText($hWnd, "", "Static2")
        ConsoleWrite("$hWnd: " & $hWnd & @TAB & "Error: " & $sError & @CRLF)
        While WinExists($hWnd)
            $iCount += 1
            If $iCount > 100 Then ExitLoop
            WinClose($hWnd) ; close the window to permit OnAutoItExitRegister() to run
            ; if ProcessClose( PID ) then OnAutoItExitRegister will not always run compleately
        WEnd
    EndIf
EndFunc   ;==>_EventProc

 Unless you find a better way, I believe this is it.

Share this post


Link to post
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
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By argumentum
      This is a UDF to handle the AutoIt Error msgbox when our awesome code goes 
      I've been using trancexx's code for the longest time and since I iron some wrinkles in my ( personal use ) UDF, decided to organize it in a dignifying way and post it.
      The ZIP with the code is in the downloads area.
      I'm posting this because most other handlers use /ErrorStdOut to catch errors and they are not that common, for us great coders 
      So makes little sense to me to run 2 EXEs for something unlikely to happen. No one made a UDF of this, so, I did.
      oh, ..there are things where this will be of no use, say, infinite recursion or what not, so, if the the AutoIt Error msgbox was to popup then this UDF should do it.
      ...let me know if you liked it, or post your views to better it.
      Cheers
      There is also an EventViewer_GetMyEntries() down this post that may come in handy.
    • By timmy2
      My script has this directive (#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6) at the top.  When I run the script from SciTE the results are what I expect and no errors are generated.  When I run the compiled executable I still get what I expect results-wise, but at the very end an AutoIt Error appears: "Error: Variable used without being declared". It cites a line number far out of range of my actual code, though perhaps it is referring to an included UDF.
      What can I do to more accurately simulate running the exe in SciTE so I can track down the undeclared variable? I suspect it's a UDF because I've added a couple recently.
      Thank you.
×
×
  • Create New...