Jump to content

About @error


Zein
 Share

Recommended Posts

Let's say I have a function named "Suite". 
Let's say "Suite" has a bunch of little functions inside of it. 

Now let's say I write a new script and call Suite(), and I want my script to exit silently if an error ever happens, at any point in the script. 

Would writing: 
 

Suite()
If @error Then exit

let me achieve that? Or do I have to specifically write the if check at every single point that I think the script could throw an error?

Link to comment
Share on other sites

4 minutes ago, FrancescoDiMuro said:

@Zein
Read more about SetError() function :)
It lets you achieve what you're trying to do ;)

Hey, reading into this, it looks like I have to manually put in SetError(). 

I may have been unclear. There are a few places that my code could throw an exception of sorts, primarily parts with arrays and their bounds.
I want the entire script to exit and stop running entirely without showing me an error. From using SetError() it looks like if one of the functions within my Suite() function call fails, I'll still have an error window pop open and subsequently not close autoit. Unless I don't understand how errors work. 

The reason this is an issue is that I'm running overnight automation tests that are a bit volatile, and if one throws an error at any point, I don't want it to hold up all subsequent runs of my tests. 

Link to comment
Share on other sites

2 minutes ago, Zein said:

From using SetError() it looks like if one of the functions within my Suite() function call fails, I'll still have an error window pop open and subsequently not close autoit.

Not if you use

If @error Then 
    Exit
Else
    ; Keep with your code
EndIf

I think that when you have functions in functions, the best way to handle an error, is to set the error using SetError() function, and then, if an error occurs, handle it, or exit the script.
This is my opinion :)

Click here to see my signature:

Spoiler

ALWAYS GOOD TO READ:

 

Link to comment
Share on other sites

I don't think I'm explaining myself very well. You're absolutely right, but let's say lines 5, 10, 15, 25, and 50 are all chances I could get an error in my function.

Do I need to add: 
 

If @error Then 
    Exit
Else
    ; Keep with your code
EndIf

to lines 5, 10, 15, 25, and 50?

Or is there a way to make it always exit on error no matter where it happens or when it happens?

Link to comment
Share on other sites

You always have to check for errors. AutoIt does not provide a Catch feature.

Runtime errors that pop up an error window are hard to catch.

Global $a[1]
$a[1] = "*"
Exit

returns:
Array variable has incorrect number of subscripts or subscript dimension range exceeded.:

This are coding errors which need to be removed by checking your input data (index etc.) before calling a function.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

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

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

Let me explain it as well as I can :)
If you have something like this:

Spoiler
Global $intError = 0, _         ; Keep the @error code
       $arrImNotAnArray, _      ; Generates the @error = 1
       $arrImAnArray3D[1][2][3] ; Generates the @error = 2

GenerateError1()
GenerateError2()

ConsoleWrite("Error = " & $intError & @CRLF)


Func GenerateError1()
    _ArrayDisplay($arrImNotAnArray)
    If @error Then $intError = @error
EndFunc

Func GenerateError2()
    _ArrayDisplay($arrImAnArray3D)
    If @error Then $intError = @error
EndFunc

 

you will only have the last error occurred.
This doesn't let you know which function caused the error, or what caused the error.
This will help you intercepting the error, and what/which function caused it:

Spoiler
Global $arrImNotAnArray, _      ; Generates the @error = 1
       $arrImAnArray3D[1][2][3] ; Generates the @error = 2

If Not GenerateError1() Then
    ConsoleWrite("Error with GenerateError1()! Error = " & @error & @CRLF)
Else
    If Not GenerateError2() Then
        ConsoleWrite("Error with GenerateError2()! Error = " & @error & @CRLF)
    Else
        ConsoleWrite("Ok!" & @CRLF)
    EndIf
EndIf


Func GenerateError1()
    _ArrayDisplay($arrImNotAnArray)
    If @error Then SetError(1, 0, 0)
EndFunc

Func GenerateError2()
    _ArrayDisplay($arrImAnArray3D)
    If @error Then SetError(2, 0, 0)
EndFunc

Then if you could post your code, or a reproducer of it, we can see if we can help you more :)
 

Edited by FrancescoDiMuro

Click here to see my signature:

Spoiler

ALWAYS GOOD TO READ:

 

Link to comment
Share on other sites

Another solution we use here!

Global $sLogFile = "path and filename of your logfile goes here" 
; Catch the MsgBox in case of an error
If @Compiled Then _AddHookApi("user32.dll", "MessageBoxW", "_Intercept_MessageBoxW", "int", "hwnd;wstr;wstr;uint")

; Your script goes here

; ===============================================================================================================================
; AutoIt displays a MsgBox for runtime errors. This MsgBox will be replaced with some text written to the error log.
; See: http://www.autoitscript.com/forum/topic/143250-grab-runtime-errors-when-script-is-run-from-a-service/
; ===============================================================================================================================
Func _Intercept_MessageBoxW($hWnd, $sText, $sTitle, $iType)
    If $sTitle = "AutoIt Error" Then
        FileWriteLine($sLogFile, $sText)
    Else
        Local $aCall = DllCall("user32.dll", "int", "MessageBoxW", _
                "hwnd", $hWnd, _
                "wstr", $sText, _
                "wstr", $sTitle, _
                "uint", $iType)
        If @error Or Not $aCall[0] Then Return 0
        Return $aCall[0]
    EndIf
EndFunc   ;==>_Intercept_MessageBoxW

Func _AddHookApi($sModuleName, $vFunctionName, $vNewFunction, $sRet = "", $sParams = "")
    Local Static $pImportDirectory, $hInstance
    If Not $pImportDirectory Then
        $hInstance = _GetModuleHandle()
        If @error Then Return SetError(1, 0, 0)
        Local $aCall = DllCall("dbghelp.dll", "ptr", "ImageDirectoryEntryToData", _
                "handle", $hInstance, _
                "boolean", 1, _ ; as an image
                "word", 1, _ ; IMAGE_DIRECTORY_ENTRY_IMPORT
                "dword*", 0)
        If @error Or Not $aCall[0] Then Return SetError(2, 0, 0)
        $pImportDirectory = $aCall[0]
    EndIf
    Local $iIsInt = IsInt($vFunctionName)
    Local $iRestore = Not IsString($vNewFunction)
    Local $tIMAGE_IMPORT_MODULE_DIRECTORY
    Local $pDirectoryOffset = $pImportDirectory
    Local $tModuleName
    Local $iInitialOffset, $iInitialOffset2
    Local $iOffset2
    Local $tBufferOffset2, $iBufferOffset2
    Local $tBuffer, $tFunctionOffset, $pOld, $fMatch
    Local Const $PAGE_READWRITE = 0x04
    While 1
        $tIMAGE_IMPORT_MODULE_DIRECTORY = DllStructCreate("dword RVAOriginalFirstThunk;" & _
                "dword TimeDateStamp;" & _
                "dword ForwarderChain;" & _
                "dword RVAModuleName;" & _
                "dword RVAFirstThunk", _
                $pDirectoryOffset)
        If Not DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk") Then ExitLoop
        $tModuleName = DllStructCreate("char Name[64]", $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAModuleName"))
        If DllStructGetData($tModuleName, "Name") = $sModuleName Then ; function from this module
            $iInitialOffset = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk")
            $iInitialOffset2 = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAOriginalFirstThunk")
            If $iInitialOffset2 = $hInstance Then $iInitialOffset2 = $iInitialOffset
            $iOffset2 = 0
            While 1
                $tBufferOffset2 = DllStructCreate("dword_ptr", $iInitialOffset2 + $iOffset2)
                $iBufferOffset2 = DllStructGetData($tBufferOffset2, 1)
                If Not $iBufferOffset2 Then ExitLoop
                If $iIsInt Then
                    If BitAND($iBufferOffset2, 0xFFFFFF) = $vFunctionName Then $fMatch = True; wanted function
                Else
                    $tBuffer = DllStructCreate("ushort Ordinal; char Name[64]", $hInstance + $iBufferOffset2)
                    If DllStructGetData($tBuffer, "Name") == $vFunctionName Then $fMatch = True; wanted function
                EndIf
                If $fMatch Then
                    $tFunctionOffset = DllStructCreate("ptr", $iInitialOffset + $iOffset2)
                    _VirtualProtect(DllStructGetPtr($tFunctionOffset), DllStructGetSize($tFunctionOffset), $PAGE_READWRITE)
                    If @error Then Return SetError(3, 0, 0)
                    $pOld = DllStructGetData($tFunctionOffset, 1)
                    If $iRestore Then
                        DllStructSetData($tFunctionOffset, 1, $vNewFunction)
                    Else
                        DllStructSetData($tFunctionOffset, 1, DllCallbackGetPtr(DllCallbackRegister($vNewFunction, $sRet, $sParams)))
                    EndIf
                    Return $pOld
                EndIf
                $iOffset2 += DllStructGetSize($tBufferOffset2)
            WEnd
            ExitLoop
        EndIf
        $pDirectoryOffset += 20 ; size of $tIMAGE_IMPORT_MODULE_DIRECTORY
    WEnd
    Return SetError(4, 0, 0)
EndFunc   ;==>_AddHookApi

Func _VirtualProtect($pAddress, $iSize, $iProtection)
    Local $aCall = DllCall("kernel32.dll", "bool", "VirtualProtect", "ptr", $pAddress, "dword_ptr", $iSize, "dword", $iProtection, "dword*", 0)
    If @error Or Not $aCall[0] Then Return SetError(1, 0, 0)
    Return 1
EndFunc   ;==>_VirtualProtect

Func _GetModuleHandle($vModule = 0)
    Local $sParamType = "ptr"
    If IsString($vModule) Then $sParamType = "wstr"
    Local $aCall = DllCall("kernel32.dll", "ptr", "GetModuleHandleW", $sParamType, $vModule)
    If @error Or Not $aCall[0] Then Return SetError(1, 0, 0)
    Return $aCall[0]
EndFunc   ;==>_GetModuleHandle
Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

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

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

That's one of the great snippets written by @trancexx - as always :)

Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

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

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

No UDFs or something like that needed. I just needed to remove two small bugs, now the following example code writes - when run as a compiled exe - all error messages generated by AutoIt to a log file. Just compile and run the resulting exe.

Global $sLogFile = @ScriptDir & "\Error_Log.txt"
; Catch the MsgBox in case of an error
If @Compiled Then _AddHookApi("user32.dll", "MessageBoxW", "_Intercept_MessageBoxW", "int", "hwnd;wstr;wstr;uint")

; ----- Example code to throw an error starts here ----
Global $a[1]
$a[1] = "*"
Exit
; ----- End of example code ----

; ===============================================================================================================================
; AutoIt displays a MsgBox for runtime errors. This MsgBox will be replaced with some text written to the error log.
; See: http://www.autoitscript.com/forum/topic/143250-grab-runtime-errors-when-script-is-run-from-a-service/
; ===============================================================================================================================
Func _Intercept_MessageBoxW($hWnd, $sText, $sTitle, $iType)
    If $sTitle = "AutoIt Error" Then
        FileWriteLine($sLogFile, $sText)
    Else
        Local $aCall = DllCall("user32.dll", "int", "MessageBoxW", _
                "hwnd", $hWnd, _
                "wstr", $sText, _
                "wstr", $sTitle, _
                "uint", $iType)
        If @error Or Not $aCall[0] Then Return 0
        Return $aCall[0]
    EndIf
EndFunc   ;==>_Intercept_MessageBoxW

Func _AddHookApi($sModuleName, $vFunctionName, $vNewFunction, $sRet = "", $sParams = "")
    Local Static $pImportDirectory, $hInstance
    If Not $pImportDirectory Then
        $hInstance = _GetModuleHandle()
        If @error Then Return SetError(1, 0, 0)
        Local $aCall = DllCall("dbghelp.dll", "ptr", "ImageDirectoryEntryToData", _
                "handle", $hInstance, _
                "boolean", 1, _ ; as an image
                "word", 1, _ ; IMAGE_DIRECTORY_ENTRY_IMPORT
                "dword*", 0)
        If @error Or Not $aCall[0] Then Return SetError(2, 0, 0)
        $pImportDirectory = $aCall[0]
    EndIf
    Local $iIsInt = IsInt($vFunctionName)
    Local $iRestore = Not IsString($vNewFunction)
    Local $tIMAGE_IMPORT_MODULE_DIRECTORY
    Local $pDirectoryOffset = $pImportDirectory
    Local $tModuleName
    Local $iInitialOffset, $iInitialOffset2
    Local $iOffset2
    Local $tBufferOffset2, $iBufferOffset2
    Local $tBuffer, $tFunctionOffset, $pOld, $fMatch
    Local Const $PAGE_READWRITE = 0x04
    While 1
        $tIMAGE_IMPORT_MODULE_DIRECTORY = DllStructCreate("dword RVAOriginalFirstThunk;" & _
                "dword TimeDateStamp;" & _
                "dword ForwarderChain;" & _
                "dword RVAModuleName;" & _
                "dword RVAFirstThunk", _
                $pDirectoryOffset)
        If Not DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk") Then ExitLoop
        $tModuleName = DllStructCreate("char Name[64]", $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAModuleName"))
        If DllStructGetData($tModuleName, "Name") = $sModuleName Then ; function from this module
            $iInitialOffset = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk")
            $iInitialOffset2 = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAOriginalFirstThunk")
            If $iInitialOffset2 = $hInstance Then $iInitialOffset2 = $iInitialOffset
            $iOffset2 = 0
            While 1
                $tBufferOffset2 = DllStructCreate("dword_ptr", $iInitialOffset2 + $iOffset2)
                $iBufferOffset2 = DllStructGetData($tBufferOffset2, 1)
                If Not $iBufferOffset2 Then ExitLoop
                If $iIsInt Then
                    If BitAND($iBufferOffset2, 0xFFFFFF) = $vFunctionName Then $fMatch = True; wanted function
                Else
                    $tBuffer = DllStructCreate("ushort Ordinal; char Name[64]", $hInstance + $iBufferOffset2)
                    If DllStructGetData($tBuffer, "Name") == $vFunctionName Then $fMatch = True; wanted function
                EndIf
                If $fMatch Then
                    $tFunctionOffset = DllStructCreate("ptr", $iInitialOffset + $iOffset2)
                    _VirtualProtect(DllStructGetPtr($tFunctionOffset), DllStructGetSize($tFunctionOffset), $PAGE_READWRITE)
                    If @error Then Return SetError(3, 0, 0)
                    $pOld = DllStructGetData($tFunctionOffset, 1)
                    If $iRestore Then
                        DllStructSetData($tFunctionOffset, 1, $vNewFunction)
                    Else
                        DllStructSetData($tFunctionOffset, 1, DllCallbackGetPtr(DllCallbackRegister($vNewFunction, $sRet, $sParams)))
                    EndIf
                    Return $pOld
                EndIf
                $iOffset2 += DllStructGetSize($tBufferOffset2)
            WEnd
            ExitLoop
        EndIf
        $pDirectoryOffset += 20 ; size of $tIMAGE_IMPORT_MODULE_DIRECTORY
    WEnd
    Return SetError(4, 0, 0)
EndFunc   ;==>_AddHookApi

Func _VirtualProtect($pAddress, $iSize, $iProtection)
    Local $aCall = DllCall("kernel32.dll", "bool", "VirtualProtect", "ptr", $pAddress, "dword_ptr", $iSize, "dword", $iProtection, "dword*", 0)
    If @error Or Not $aCall[0] Then Return SetError(1, 0, 0)
    Return 1
EndFunc   ;==>_VirtualProtect

Func _GetModuleHandle($vModule = 0)
    Local $sParamType = "ptr"
    If IsString($vModule) Then $sParamType = "wstr"
    Local $aCall = DllCall("kernel32.dll", "ptr", "GetModuleHandleW", $sParamType, $vModule)
    If @error Or Not $aCall[0] Then Return SetError(1, 0, 0)
    Return $aCall[0]
EndFunc   ;==>_GetModuleHandle

 

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

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

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

4 minutes ago, water said:

No UDFs or something like that needed. I just needed to remove two small bugs, now the following example code writes - when run as a compiled exe - all error messages generated by AutoIt to a log file. Just compile and run the resulting exe.

Global $sLogFile = @ScriptDir & "\Error_Log.txt"
; Catch the MsgBox in case of an error
If @Compiled Then _AddHookApi("user32.dll", "MessageBoxW", "_Intercept_MessageBoxW", "int", "hwnd;wstr;wstr;uint")

; ----- Example code to throw an error starts here ----
Global $a[1]
$a[1] = "*"
Exit
; ----- End of example code ----

; ===============================================================================================================================
; AutoIt displays a MsgBox for runtime errors. This MsgBox will be replaced with some text written to the error log.
; See: http://www.autoitscript.com/forum/topic/143250-grab-runtime-errors-when-script-is-run-from-a-service/
; ===============================================================================================================================
Func _Intercept_MessageBoxW($hWnd, $sText, $sTitle, $iType)
    If $sTitle = "AutoIt Error" Then
        FileWriteLine($sLogFile, $sText)
    Else
        Local $aCall = DllCall("user32.dll", "int", "MessageBoxW", _
                "hwnd", $hWnd, _
                "wstr", $sText, _
                "wstr", $sTitle, _
                "uint", $iType)
        If @error Or Not $aCall[0] Then Return 0
        Return $aCall[0]
    EndIf
EndFunc   ;==>_Intercept_MessageBoxW

Func _AddHookApi($sModuleName, $vFunctionName, $vNewFunction, $sRet = "", $sParams = "")
    Local Static $pImportDirectory, $hInstance
    If Not $pImportDirectory Then
        $hInstance = _GetModuleHandle()
        If @error Then Return SetError(1, 0, 0)
        Local $aCall = DllCall("dbghelp.dll", "ptr", "ImageDirectoryEntryToData", _
                "handle", $hInstance, _
                "boolean", 1, _ ; as an image
                "word", 1, _ ; IMAGE_DIRECTORY_ENTRY_IMPORT
                "dword*", 0)
        If @error Or Not $aCall[0] Then Return SetError(2, 0, 0)
        $pImportDirectory = $aCall[0]
    EndIf
    Local $iIsInt = IsInt($vFunctionName)
    Local $iRestore = Not IsString($vNewFunction)
    Local $tIMAGE_IMPORT_MODULE_DIRECTORY
    Local $pDirectoryOffset = $pImportDirectory
    Local $tModuleName
    Local $iInitialOffset, $iInitialOffset2
    Local $iOffset2
    Local $tBufferOffset2, $iBufferOffset2
    Local $tBuffer, $tFunctionOffset, $pOld, $fMatch
    Local Const $PAGE_READWRITE = 0x04
    While 1
        $tIMAGE_IMPORT_MODULE_DIRECTORY = DllStructCreate("dword RVAOriginalFirstThunk;" & _
                "dword TimeDateStamp;" & _
                "dword ForwarderChain;" & _
                "dword RVAModuleName;" & _
                "dword RVAFirstThunk", _
                $pDirectoryOffset)
        If Not DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk") Then ExitLoop
        $tModuleName = DllStructCreate("char Name[64]", $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAModuleName"))
        If DllStructGetData($tModuleName, "Name") = $sModuleName Then ; function from this module
            $iInitialOffset = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk")
            $iInitialOffset2 = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAOriginalFirstThunk")
            If $iInitialOffset2 = $hInstance Then $iInitialOffset2 = $iInitialOffset
            $iOffset2 = 0
            While 1
                $tBufferOffset2 = DllStructCreate("dword_ptr", $iInitialOffset2 + $iOffset2)
                $iBufferOffset2 = DllStructGetData($tBufferOffset2, 1)
                If Not $iBufferOffset2 Then ExitLoop
                If $iIsInt Then
                    If BitAND($iBufferOffset2, 0xFFFFFF) = $vFunctionName Then $fMatch = True; wanted function
                Else
                    $tBuffer = DllStructCreate("ushort Ordinal; char Name[64]", $hInstance + $iBufferOffset2)
                    If DllStructGetData($tBuffer, "Name") == $vFunctionName Then $fMatch = True; wanted function
                EndIf
                If $fMatch Then
                    $tFunctionOffset = DllStructCreate("ptr", $iInitialOffset + $iOffset2)
                    _VirtualProtect(DllStructGetPtr($tFunctionOffset), DllStructGetSize($tFunctionOffset), $PAGE_READWRITE)
                    If @error Then Return SetError(3, 0, 0)
                    $pOld = DllStructGetData($tFunctionOffset, 1)
                    If $iRestore Then
                        DllStructSetData($tFunctionOffset, 1, $vNewFunction)
                    Else
                        DllStructSetData($tFunctionOffset, 1, DllCallbackGetPtr(DllCallbackRegister($vNewFunction, $sRet, $sParams)))
                    EndIf
                    Return $pOld
                EndIf
                $iOffset2 += DllStructGetSize($tBufferOffset2)
            WEnd
            ExitLoop
        EndIf
        $pDirectoryOffset += 20 ; size of $tIMAGE_IMPORT_MODULE_DIRECTORY
    WEnd
    Return SetError(4, 0, 0)
EndFunc   ;==>_AddHookApi

Func _VirtualProtect($pAddress, $iSize, $iProtection)
    Local $aCall = DllCall("kernel32.dll", "bool", "VirtualProtect", "ptr", $pAddress, "dword_ptr", $iSize, "dword", $iProtection, "dword*", 0)
    If @error Or Not $aCall[0] Then Return SetError(1, 0, 0)
    Return 1
EndFunc   ;==>_VirtualProtect

Func _GetModuleHandle($vModule = 0)
    Local $sParamType = "ptr"
    If IsString($vModule) Then $sParamType = "wstr"
    Local $aCall = DllCall("kernel32.dll", "ptr", "GetModuleHandleW", $sParamType, $vModule)
    If @error Or Not $aCall[0] Then Return SetError(1, 0, 0)
    Return $aCall[0]
EndFunc   ;==>_GetModuleHandle

 

I can't just run the script uncompiled by putting the script where it's needed? 
Compiling it could be really inconvenient, but not the end of the world. 

 

2 minutes ago, pixelsearch said:

@Zein : also don't forget there are functions that set @error <> 0 and it's acceptable.
For example, Clipget() sets @error to 1 if clipboard is empty, what now ?
Maybe your script did manage that and you didn't consider it like a fatal error :)

Oh I understand. That's not an issue for me just yet. 

Link to comment
Share on other sites

Only as a compiled exe you get the MsgBox. When you run the script from SciTE you get errors as text in the SciTE output pane.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

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

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

This is not my experience at the moment. If I get an array out of bounds error it gives me a MsgBox. But I do right click -> run script.
And overnight I make a windows task to run autoit3.exe with the script as a param.

Would that code get around these cases too? 

Link to comment
Share on other sites

The "easiest" way to prevent the script from crashing with an error, is to put error checking in wherever you think it might encounter an error, and figure out how to get past it without crashing the script.

For example, you use _FileListToArray to get a list of files, there are no files in the folder you're looking in that matches, no array is created. If your code doesn't take into account the fact that the function might not return an array and you try to process a non-existent array, that will cause an error. You need to prevent it from trying to process the array that isn't there.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

2 hours ago, BrewManNH said:

The "easiest" way to prevent the script from crashing with an error, is to put error checking in wherever you think it might encounter an error, and figure out how to get past it without crashing the script.

For example, you use _FileListToArray to get a list of files, there are no files in the folder you're looking in that matches, no array is created. If your code doesn't take into account the fact that the function might not return an array and you try to process a non-existent array, that will cause an error. You need to prevent it from trying to process the array that isn't there.

I do plan to make my code more bulletproof in terms of error checks at the right spot, but for now when I'm running overnight tests, I'd rather be able to run what I have without worrying about a popup window. 

Although I always assumed that ensuring you're within UBound - 1 of the dimension then you're safe with regards to the array you're using. 

Link to comment
Share on other sites

22 minutes ago, Zein said:

Although I always assumed that ensuring you're within UBound - 1 of the dimension then you're safe with regards to the array you're using. 

If there's no array, there's no UBound.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...