Zein Posted September 10, 2018 Share Posted September 10, 2018 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 More sharing options...
FrancescoDiMuro Posted September 10, 2018 Share Posted September 10, 2018 @Zein Read more about SetError() function It lets you achieve what you're trying to do Click here to see my signature: Spoiler ALWAYS GOOD TO READ: Forum Rules Forum Etiquette Link to comment Share on other sites More sharing options...
Zein Posted September 10, 2018 Author Share Posted September 10, 2018 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 More sharing options...
FrancescoDiMuro Posted September 10, 2018 Share Posted September 10, 2018 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: Forum Rules Forum Etiquette Link to comment Share on other sites More sharing options...
Zein Posted September 10, 2018 Author Share Posted September 10, 2018 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 More sharing options...
water Posted September 10, 2018 Share Posted September 10, 2018 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. user4157124 1 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 More sharing options...
FrancescoDiMuro Posted September 10, 2018 Share Posted September 10, 2018 (edited) 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 September 10, 2018 by FrancescoDiMuro Click here to see my signature: Spoiler ALWAYS GOOD TO READ: Forum Rules Forum Etiquette Link to comment Share on other sites More sharing options...
water Posted September 10, 2018 Share Posted September 10, 2018 (edited) Another solution we use here! expandcollapse popupGlobal $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 September 10, 2018 by water FrancescoDiMuro 1 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 More sharing options...
FrancescoDiMuro Posted September 10, 2018 Share Posted September 10, 2018 @water Nice snippet as always! Click here to see my signature: Spoiler ALWAYS GOOD TO READ: Forum Rules Forum Etiquette Link to comment Share on other sites More sharing options...
water Posted September 10, 2018 Share Posted September 10, 2018 (edited) That's one of the great snippets written by @trancexx - as always Edited September 10, 2018 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 More sharing options...
Zein Posted September 10, 2018 Author Share Posted September 10, 2018 That looks really great. I'm new to AutoIT and I'm so impressed by how often the community pumps out great code. Is there anything I need (like specific UDFs) to use that or should it just be plug and play? Link to comment Share on other sites More sharing options...
water Posted September 10, 2018 Share Posted September 10, 2018 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. expandcollapse popupGlobal $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 More sharing options...
pixelsearch Posted September 10, 2018 Share Posted September 10, 2018 @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 Link to comment Share on other sites More sharing options...
Zein Posted September 10, 2018 Author Share Posted September 10, 2018 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. expandcollapse popupGlobal $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 More sharing options...
water Posted September 10, 2018 Share Posted September 10, 2018 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 More sharing options...
Zein Posted September 10, 2018 Author Share Posted September 10, 2018 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 More sharing options...
BrewManNH Posted September 10, 2018 Share Posted September 10, 2018 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 GudeHow 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 More sharing options...
Zein Posted September 10, 2018 Author Share Posted September 10, 2018 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 More sharing options...
BrewManNH Posted September 10, 2018 Share Posted September 10, 2018 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. FrancescoDiMuro 1 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 GudeHow 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 More sharing options...
Zein Posted September 10, 2018 Author Share Posted September 10, 2018 That I would never be able to catch myself. Naturally I'd assume the UBound would just be 0. But I suppose that's a result of only coding with statically typed languages for the past ~7 years. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now