Jump to content

OnDebugMsgBox ( for the dreaded "AutoIt Error" msgbox )

Recommended Posts


This is a UDF to handle the AutoIt Error msgbox when our awesome code goes :oops:

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 :king:
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.


There is also an EventViewer_GetMyEntries() down this post that may come in handy.

Edited by argumentum
Link to post
Share on other sites

What's New in Version 1.2020.5.26
added: logfile self maintenance - _DebugMsgBox_PriorLogSize()
added: error return - _DebugMsgBox_AddHookApiError()
fixed: Au3Stripper error on DllCallbackRegister() and related when /RM is used.
added: TimerDiff() and @UserName to the report.
added: _DebugMsgBox_EventLogId() - ( no real use for us here, added for completeness )
added: _DebugMsgBox_EventLogCategory() - ( no real use for us here, added for completeness  )
added: _DebugMsgBox_EventLogBinaryData() - ( no real use for us here, added for completeness  )

What's New in Version 1.2020.5.25
added: _DebugMsgBox_GetUDFversion() ; Get UDF version
added: _DebugMsgBox_EXEversion([$sVersion]) ; Set / Get executable file version for report
fixed: needless folder creations

What's New in Version 1.2020.5.24
initial release


The ZIP with the code is in the downloads area.

Link to post
Share on other sites

The default value for _DebugMsgBox_EventLogId() is 1000, and so is for AutoIt most of the time.
If you want to read your entries from the Events log, you may use these:

#include <EventLog.au3>
#include <Array.au3>

Example1() ; DLL way
Func Example1()
    Local $t = TimerInit(), $aArray = EventLog_FindMyErrorInLast(5)
    If @error Then MsgBox(0, @ScriptName, "there was an error doing this", 10)
    _ArrayDisplay($aArray, "EventLog_FindMyErrorInLast() - w/ DLL - " & TimerDiff($t))
EndFunc   ;==>Example

Func EventLog_FindMyErrorInLast($iMaxReturn = 10, $iMaxSampleCount = 1000, $iEventIdentifier = 1000)
    ; $iMaxReturn = max. records to return
    ; $iMaxSampleCount = max. sample reads searching for events
    ; $iEventIdentifier = _DebugMsgBox_EventLogId()
    Local $hEventLog, $aEvent
    Local $i = 0, $aArray[$iMaxReturn + 1][14]
    $aArray[0][0] = 0
    $aArray[0][1] = "Record number"
    $aArray[0][2] = "Submitted Date Time"
    $aArray[0][4] = "Generated Date Time"
    $aArray[0][6] = "Event ID"
    $aArray[0][7] = "Type #"
    $aArray[0][8] = "Type Str."
    $aArray[0][9] = "Category"
    $aArray[0][10] = "Source"
    $aArray[0][11] = "Computer"
    $aArray[0][12] = "Username"
    $aArray[0][13] = "Description"

    ; Read most current event records
    $hEventLog = _EventLog__Open("", "Application")
    If $hEventLog = 0 Then
        ReDim $aArray[$i + 1][14]
        $aArray[0][0] = $i
        Return SetError(1, 0, $aArray)

    For $n = 1 To $iMaxSampleCount
        $aEvent = _EventLog__Read($hEventLog, True, False)
        If $aEvent[0] = False Then ExitLoop
        If $aEvent[6] <> $iEventIdentifier Or $aEvent[8] <> 'Error' Or $aEvent[9] <> 0 Then ContinueLoop
        $i += 1
        For $m = 1 To 13
            Switch $m
                Case 2, 4
                    $aArray[$i][$m] = $aEvent[$m] & " " & $aEvent[$m + 1]
                Case 3, 5
                Case Else
                    $aArray[$i][$m] = $aEvent[$m]
        If $i = $iMaxReturn Then ExitLoop


    ReDim $aArray[$i + 1][14]
    $aArray[0][0] = $i
    Return $aArray
EndFunc   ;==>EventLog_FindMyErrorInLast


Example2() ; WMI way
Func Example2()  ;  https://www.autoitscript.com/forum/topic/202832-ondebugmsgbox-for-the-dreaded-autoit-error-msgbox/?do=findComment&comment=1456279
    Local $t = TimerInit(), $aArray = EventViewer_GetMyEntries(5)
    If @error Then MsgBox(0, @ScriptName, "there was an error doing this", 10)
    _ArrayDisplay($aArray, "EventViewer_GetMyEntries() - w/ WMI - " & TimerDiff($t))
EndFunc   ;==>Example

Func EventViewer_GetMyEntries($iMaxReturn = 10, $iEventIdentifier = 1000) ; $iMaxReturn = 0 means no limit ;
    ; based out of https://www.autoitscript.com/forum/topic/141626-collecting-event-logs-question/
    Local $v, $r, $s, $iCount = 0, $wbemFlagReturnImmediately = 0x10, $wbemFlagForwardOnly = 0x20
    Local $aOutput[100][7]
    $aOutput[0][1] = "Category"
    $aOutput[0][2] = "RecordNumber"
    $aOutput[0][3] = "Type"
    $aOutput[0][4] = "User"
    $aOutput[0][5] = "TimeGenerated"
    $aOutput[0][6] = "InsertionString(s)"

    Local $objItem, $objWMIService = ObjGet("winmgmts:\\.\")

    Local $sSQL = "SELECT Category,RecordNumber,Type,User,TimeGenerated,InsertionStrings"
    $sSQL &= " FROM Win32_NTLogEvent WHERE "
;~  $sSQL &= "Category = 0 AND " ;   others tend to have Category = 100
    $sSQL &= "Type = 'Error' AND " ;  and Type = 'Information'
    $sSQL &= "EventIdentifier = " & $iEventIdentifier

    Local $colItems = $objWMIService.ExecQuery($sSQL, "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

    If IsObj($colItems) Then
        For $objItem In $colItems
            $iCount += 1
            If $iCount = UBound($aOutput) Then ReDim $aOutput[UBound($aOutput) + 100][7]
            $aOutput[$iCount][1] = $objItem.Category
            $aOutput[$iCount][2] = $objItem.RecordNumber
            $aOutput[$iCount][3] = $objItem.Type
            $aOutput[$iCount][4] = $objItem.User
            $aOutput[$iCount][5] = WMIDateStringToDate($objItem.TimeGenerated)
            $s = ""
            $v = $objItem.InsertionStrings
            For $r In $v
                $s &= $r & @CRLF
            $aOutput[$iCount][6] = $s
            If $iCount = $iMaxReturn Then ExitLoop
        ReDim $aOutput[$iCount + 1][7]
        $aOutput[0][0] = $iCount
        Return SetError(1, $iCount, $aOutput)
    ReDim $aOutput[$iCount + 1][7]
    $aOutput[0][0] = $iCount
    Return SetError(0, $iCount, $aOutput)
EndFunc   ;==>EventViewer_GetMyEntries

Func WMIDateStringToDate($dtmDate)
    Return (StringMid($dtmDate, 5, 2) & "/" & _
            StringMid($dtmDate, 7, 2) & "/" & StringLeft($dtmDate, 4) _
             & " " & StringMid($dtmDate, 9, 2) & ":" & StringMid($dtmDate, 11, 2) & ":" & StringMid($dtmDate, 13, 2))
EndFunc   ;==>WMIDateStringToDate


Edited by argumentum
better code
Link to post
Share on other sites
  • 4 weeks later...

Has been added to the wiki :)

My UDFs and Tutorials:


Active Directory (NEW 2022-02-19 - Version - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version - Download
Outlook Tools (2019-07-22 - Version - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

ADO - Wiki
WebDriver - Wiki


Link to post
Share on other sites

What's New in Version 2.2020.6.25
added: _DebugMsgBox_WinVerStr() to set or get the version string for the Windows.
added: Set/Get show of AutoIt version on title when not compiled. Default is True/Show.
    (this is because I've found myself running beta inadvertently and scratching my head)
changed: _DebugMsgBox_LogFile(). now an empty string will overwrite a log in @TempDir,
    to turn it OFF, set to FALSE. ( read remarks )

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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Iraj
      I was exploring as I saw the below URL which reads the event logs from specific type (Application, Security, System, etc.)
      So, I was in need to read a specific event id instead of the type of event, i.e. I need to read event id 1074 which lands under Security type.
      Any assistance will be grateful.
      Happy new year in advance!!
    • By argumentum
      #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 ?
    • 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.
    • By RedneckTech
      Yea, i know, dont trust M$, but its not for me. its for general purpose. All of the logs for this application are in the event viewer. Im sorry if ive just missed this, but I need to find a way to poll the event viewer log for any events from MSE and then record that to a file somehow. I've been looking and cant find anything that seems helpful. I may just be seeing what i need and not noticing it. Any help would be greatly appreciated
  • Create New...