argumentum

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

4 posts in this topic

#1 ·  Posted (edited)

#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

1 person likes this

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

You're Wellcome.

 

Saludos

1 person likes this

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

  • Similar Content

    • timmy2
      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.