-
Posts
11,553 -
Joined
-
Last visited
-
Days Won
61
mLipok last won the day on September 13
mLipok had the most liked content!
About mLipok

- Birthday 07/19/1978
Profile Information
-
Member Title
I'm nitpicky sometimes.
-
Location
Europe, Poland, Upper Silesia, Zabrze
-
Interests
¯\_(ツ)_/¯
mLipok's Achievements
-
Danyfirex reacted to a post in a topic:
Avoid "AutoIt Error" message box in unknown errors
-
donnyh13 reacted to a post in a topic:
Avoid "AutoIt Error" message box in unknown errors
-
So here is my recent snippet which uses new function: Json_ArrayPut() inspired by @Jos AddLocation() #include "Json.au3" ConsoleWrite("- Test8d() :" & @CRLF & Test8d() & @CRLF) Func Test8d() ; Your three JSON strings ;~ Local $Json1 = '{"name":"John","age":30,"locations":[]}' Local $Json1 = '{"name":"John","age":30}' Local $Json2 = '{"City":"Paris","Country":"France"}' Local $Json3 = '{"City":"London","Country":"England"}' ; create object from first JSON string Local $obj1 = Json_Decode($Json1) ConsoleWrite('counting elements in "locations" = ' & UBound(Json_ObjGet($obj1, "locations")) & ' ERR=' & @error & ' EXT=' & @extended & @CRLF) ; add second JSON string to the object as an last elemnt of "JSON_ARRAY" structure called "locations" Json_ArrayPut($obj1, "locations", $Json2) ;~ Json_ArrayPut($obj1, "locations.main", $Json2) ConsoleWrite('counting elements in "locations" = ' & UBound(Json_ObjGet($obj1, "locations")) & ' ERR=' & @error & ' EXT=' & @extended & @CRLF) ; add third JSON string to the object as an last elemnt of "JSON_ARRAY" structure called "locations" Json_ArrayPut($obj1, "locations", $Json3) ;~ Json_ArrayPut($obj1, "locations.addtional", $Json3) ConsoleWrite('counting elements in "locations" = ' & UBound(Json_ObjGet($obj1, "locations")) & ' ERR=' & @error & ' EXT=' & @extended & @CRLF) Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) Return $final EndFunc ;==>Test8d Func Json_ArrayPut(ByRef $oObj, $Key, $vJson_toAdd) Json_IsObject($oObj) If @error Then Return SetError(1, 1) ;~ Local $current = Json_Encode($oObj, $JSON_PRETTY_PRINT) ;~ ConsoleWrite('$current = ' & $current & @CRLF) ;~ ConsoleWrite('$vJson_toAdd = ' & $vJson_toAdd & @CRLF) Local $count = UBound(Json_ObjGet($oObj, $Key)) ;~ ConsoleWrite($count & @CRLF) ;~ ConsoleWrite(VarGetType($aFound) & @CRLF) Local $oJson_snippet If (IsString($vJson_toAdd) And StringLen($vJson_toAdd)) Then $oJson_snippet = Json_Decode($vJson_toAdd) If @error Then Return SetError(3, 3) ElseIf Json_IsObject($vJson_toAdd) Then $oJson_snippet = $vJson_toAdd ; just $vJson_toAdd be passed to Json_Put() Else Return SetError(4, 3) EndIf Json_Put($oObj, "." & $Key & "[" & $count & "]", $oJson_snippet) If @error Then Return SetError(5, 0) EndFunc ;==>Json_ArrayPut
-
#include "Json.au3" ;~ ConsoleWrite("- Test8a() :" & @CRLF & Test8a() & @CRLF) ;~ ConsoleWrite("- Test8b() :" & @CRLF & Test8b() & @CRLF) ConsoleWrite("- Test8c() :" & @CRLF & Test8c() & @CRLF) Func Test8a() ; Your three JSON strings Local $Json1 = '{"name":"John","age":30,"locations":[]}' Local $Json2 = '{"City":"Paris","Country":"France"}' Local $Json3 = '{"City":"London","Country":"England"}' ; Decode Local $obj1 = Json_Decode($Json1) Json_ObjPut($obj1, "locations", Json_Decode("[" & $Json2 & "," & $Json3 & "]")) Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) Return $final EndFunc ;==>Test8a Func Test8b() ; Your three JSON strings Local $Json1 = '{"name":"John","age":30,"locations":[]}' ; Decode Local $obj1 = Json_Decode($Json1) ; as for first step I only know the first location Local $Json2 = '{"City":"Paris","Country":"France"}' Json_ObjPut($obj1, "locations", Json_Decode("[" & $Json2 & "]")) ; and a while later I was notified about new location, so here to add them ; firstly get current known locations Local $oLocations = Json_ObjGet($obj1, "locations") Local $sCurrentLocations = Json_Encode($oLocations, $JSON_PRETTY_PRINT) ConsoleWrite(@ScriptLineNumber & ' $sCurrentLocations= ' & $sCurrentLocations & @CRLF) ; new location Local $Json3 = '{"City":"London","Country":"England"}' ; concatenate two JSON string, as first is JSON ARRAY object StringTrimRight(*, 1) must bu used Local $sJson_concatenated = "[" & StringTrimRight($sCurrentLocations, 1) & ',' & $Json3 & "]" ;~ ConsoleWrite(@ScriptLineNumber & ' $sJson_concatenated= ' & $sJson_concatenated & @CRLF) Json_ObjPut($obj1, "locations", Json_Decode($sJson_concatenated)) ; issue: it replace it instead add new object to the array Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) Return $final EndFunc ;==>Test8b Func Test8c() ; Your three JSON strings Local $Json1 = '{"name":"John","age":30}' ; Decode Local $obj1 = Json_Decode($Json1) ; add empty "locations" JSOR ARRAY element Json_ObjPut($obj1, "locations", Json_Decode('[]')) Local $step0 = Json_Encode($obj1, $JSON_PRETTY_PRINT) ConsoleWrite(@ScriptLineNumber & ' $step0= ' & $step0 & @CRLF) Local $oLocations, $sCurrentLocations, $sJson_concatenated ; get current known locations $oLocations = Json_ObjGet($obj1, "locations") $sCurrentLocations = Json_Encode($oLocations, $JSON_PRETTY_PRINT) If $sCurrentLocations = '[]' Then $sCurrentLocations = '' ConsoleWrite(@ScriptLineNumber & ' $sCurrentLocations= ' & $sCurrentLocations & @CRLF) ; as for first step - here we know only the first location Local $Json2 = '{"City":"Paris","Country":"France"}' ; concatenate two JSON string, as first is JSON ARRAY object StringTrimRight(*, 1) must bu used $sJson_concatenated = (($sCurrentLocations) ? (StringTrimRight($sCurrentLocations, 1) & ',') : ('[')) & $Json2 & "]" ;~ ConsoleWrite(@ScriptLineNumber & ' $sJson_concatenated= ' & $sJson_concatenated & @CRLF) Json_ObjPut($obj1, "locations", Json_Decode($sJson_concatenated)) Local $step1 = Json_Encode($obj1, $JSON_PRETTY_PRINT) ConsoleWrite(@ScriptLineNumber & ' $step1= ' & $step1 & @CRLF) ; and a while later I was notified about new location, so here to add them ; second step - again get current "Locations" STRING $oLocations = Json_ObjGet($obj1, "locations") $sCurrentLocations = Json_Encode($oLocations, $JSON_PRETTY_PRINT) If $sCurrentLocations = '[]' Then $sCurrentLocations = '' ConsoleWrite(@ScriptLineNumber & ' $sCurrentLocations= ' & $sCurrentLocations & @CRLF) ; new location Local $Json3 = '{"City":"London","Country":"England"}' ; concatenate two JSON string, as first is JSON ARRAY object StringTrimRight(*, 1) must bu used $sJson_concatenated = (($sCurrentLocations) ? (StringTrimRight($sCurrentLocations, 1) & ',') : ('[')) & $Json3 & "]" ;~ ConsoleWrite(@ScriptLineNumber & ' $sJson_concatenated= ' & $sJson_concatenated & @CRLF) Json_ObjPut($obj1, "locations", Json_Decode($sJson_concatenated)) ; issue: it replace it instead add new object to the array Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) Return $final EndFunc ;==>Test8c as for now I was working on: ;~ https://www.autoitscript.com/forum/topic/148114-a-non-strict-json-udf-jsmn/page/20/#comment-1547453 #include "Json.au3" ;~ ConsoleWrite("- Test8a() :" & @CRLF & Test8a() & @CRLF) ;~ ConsoleWrite("- Test8b() :" & @CRLF & Test8b() & @CRLF) ConsoleWrite("- Test8c() :" & @CRLF & Test8c() & @CRLF) Func Test8a() ; Your three JSON strings Local $Json1 = '{"name":"John","age":30,"locations":[]}' Local $Json2 = '{"City":"Paris","Country":"France"}' Local $Json3 = '{"City":"London","Country":"England"}' ; Decode Local $obj1 = Json_Decode($Json1) Json_ObjPut($obj1, "locations", Json_Decode("[" & $Json2 & "," & $Json3 & "]")) Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) Return $final EndFunc ;==>Test8a Func Test8b() ; Your three JSON strings Local $Json1 = '{"name":"John","age":30,"locations":[]}' ; Decode Local $obj1 = Json_Decode($Json1) ; as for first step I only know the first location Local $Json2 = '{"City":"Paris","Country":"France"}' Json_ObjPut($obj1, "locations", Json_Decode("[" & $Json2 & "]")) ; and a while later I was notified about new location, so here to add them ; firstly get current known locations Local $oLocations = Json_ObjGet($obj1, "locations") Local $sCurrentLocations = Json_Encode($oLocations, $JSON_PRETTY_PRINT) ConsoleWrite(@ScriptLineNumber & ' $sCurrentLocations= ' & $sCurrentLocations & @CRLF) ; new location Local $Json3 = '{"City":"London","Country":"England"}' ; concatenate two JSON string, as first is JSON ARRAY object StringTrimRight(*, 1) must bu used Local $sJson_concatenated = "[" & StringTrimRight($sCurrentLocations, 1) & ',' & $Json3 & "]" ;~ ConsoleWrite(@ScriptLineNumber & ' $sJson_concatenated= ' & $sJson_concatenated & @CRLF) Json_ObjPut($obj1, "locations", Json_Decode($sJson_concatenated)) ; issue: it replace it instead add new object to the array Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) Return $final EndFunc ;==>Test8b Func Test8c() ; Your three JSON strings Local $Json1 = '{"name":"John","age":30}' ; Decode Local $obj1 = Json_Decode($Json1) ; add empty "locations" JSOR ARRAY element Json_ObjPut($obj1, "locations", Json_Decode('[]')) Local $step0 = Json_Encode($obj1, $JSON_PRETTY_PRINT) ConsoleWrite(@ScriptLineNumber & ' $step0= ' & $step0 & @CRLF) Local $oLocations, $sCurrentLocations, $sJson_concatenated ; get current known locations $oLocations = Json_ObjGet($obj1, "locations") $sCurrentLocations = Json_Encode($oLocations, $JSON_PRETTY_PRINT) If $sCurrentLocations = '[]' Then $sCurrentLocations = '' ConsoleWrite(@ScriptLineNumber & ' $sCurrentLocations= ' & $sCurrentLocations & @CRLF) ; as for first step - here we know only the first location Local $Json2 = '{"City":"Paris","Country":"France"}' ; concatenate two JSON string, as first is JSON ARRAY object StringTrimRight(*, 1) must bu used $sJson_concatenated = (($sCurrentLocations) ? (StringTrimRight($sCurrentLocations, 1) & ',') : ('[')) & $Json2 & "]" ;~ ConsoleWrite(@ScriptLineNumber & ' $sJson_concatenated= ' & $sJson_concatenated & @CRLF) Json_ObjPut($obj1, "locations", Json_Decode($sJson_concatenated)) Local $step1 = Json_Encode($obj1, $JSON_PRETTY_PRINT) ConsoleWrite(@ScriptLineNumber & ' $step1= ' & $step1 & @CRLF) ; and a while later I was notified about new location, so here to add them ; second step - again get current "Locations" STRING $oLocations = Json_ObjGet($obj1, "locations") $sCurrentLocations = Json_Encode($oLocations, $JSON_PRETTY_PRINT) If $sCurrentLocations = '[]' Then $sCurrentLocations = '' ConsoleWrite(@ScriptLineNumber & ' $sCurrentLocations= ' & $sCurrentLocations & @CRLF) ; new location Local $Json3 = '{"City":"London","Country":"England"}' ; concatenate two JSON string, as first is JSON ARRAY object StringTrimRight(*, 1) must bu used $sJson_concatenated = (($sCurrentLocations) ? (StringTrimRight($sCurrentLocations, 1) & ',') : ('[')) & $Json3 & "]" ;~ ConsoleWrite(@ScriptLineNumber & ' $sJson_concatenated= ' & $sJson_concatenated & @CRLF) Json_ObjPut($obj1, "locations", Json_Decode($sJson_concatenated)) ; issue: it replace it instead add new object to the array Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) Return $final EndFunc ;==>Test8c but yours solutions looks nice. Will take a look on them.
-
Your answer inspire me to solve it this way: #include "Json.au3" ConsoleWrite("- Test8b() : " & Test8b() & @CRLF) Func Test8b() ; Your three JSON strings Local $Json1 = '{"name":"John","age":30,"locations":[]}' ; Decode Local $obj1 = Json_Decode($Json1) ; as for first step I only know the first location Local $Json2 = '{"City":"Paris","Country":"France"}' Json_ObjPut($obj1, "locations", Json_Decode("[" & $Json2 & "]")) ; and a while later I was notified about new location, so here to add them ; firstly get current known locations Local $oLocations = Json_ObjGet($obj1, "locations") Local $sCurrentLocations = Json_Encode($oLocations, $JSON_PRETTY_PRINT) ; new location Local $Json3 = '{"City":"London","Country":"England"}' ; concatenate two JSON string, as first is JSON ARRAY object StringTrimRight(*, 1) must bu used Local $sJson_concatenated = "[" & StringTrimRight($sCurrentLocations, 1) & ',' & $Json3 & "]" Json_ObjPut($obj1, "locations", Json_Decode($sJson_concatenated)) ; issue: it replace it instead add new object to the array Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) ConsoleWrite($final & @CRLF) EndFunc ;==>Test8b
-
but I was wondering also about something like this: #include "Json.au3" ConsoleWrite("- Test8b() : " & Test8b() & @CRLF) Func Test8b() ; Your three JSON strings Local $Json1 = '{"name":"John","age":30,"locations":[]}' ; Decode Local $obj1 = Json_Decode($Json1) ; as for first step I only know the first location Local $Json2 = '{"City":"Paris","Country":"France"}' Json_ObjPut($obj1, "locations", Json_Decode("[" & $Json2 & "]")) ; .... and a while later I was notified about new location, so here I try to add them ..... Local $Json3 = '{"City":"London","Country":"England"}' Json_ObjPut($obj1, "locations", Json_Decode("[" & $Json3 & "]")) ; issue: it replace it instead add new object to the array Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) ConsoleWrite($final & @CRLF) EndFunc ;==>Test8b as for now with no success
-
Simple and effective. Simply brilliant. Thanks.
-
mLipok reacted to a post in a topic:
A Non-Strict JSON UDF (JSMN)
-
Avoid "AutoIt Error" message box in unknown errors
mLipok replied to EKY32's topic in AutoIt General Help and Support
As usually I love your answer my friend. As always, I really liked your answer, my friend. All is clear for me. Thanks. So. @Parsix In your opinion, does this example fully meet your needs for using Au3Stripper with the @trancexx script , I mean all the possibilities of the /SO /PE /RM parameters? -
Avoid "AutoIt Error" message box in unknown errors
mLipok replied to EKY32's topic in AutoIt General Help and Support
Now it is. Thanks. So here is my solution for this script: ;~ https://www.autoitscript.com/forum/topic/154081-avoid-autoit-error-message-box-in-unknown-errors/page/4/#findComment-1547476 #Region - AutoIt3Wrapper directives section ; General section #AutoIt3Wrapper_UseX64=n #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_Compression=4 ; Au3Check section #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 6 -w 7 ; Au3Stripper section #AutoIt3Wrapper_Run_Au3Stripper=y ;~ #Au3Stripper_Parameters=/SO /PE #Au3Stripper_Parameters=/SO /PE /RM #AutoIt3Wrapper_Au3Stripper_OnError=f ;~ #Au3Stripper_Ignore_Funcs=Intercept_MessageBoxW ;~ #Au3Stripper_Ignore_Funcs=__AddHookApi_DllCallbackRegister_wrapper #EndRegion - AutoIt3Wrapper directives section #include <WinApi.au3> #Region - exmaple ;~ AddHookApi("user32.dll", "MessageBoxW", "Intercept_MessageBoxW", "int", "hwnd;wstr;wstr;uint") AddHookApi("user32.dll", "MessageBoxW", FuncName(Intercept_MessageBoxW), "int", "hwnd;wstr;wstr;uint") MsgBox(0, 'Test', 'Some normal MsgBox text') DllStructCreate("byte[123456789097]") ; This is a deliberate action intended to display an error, as this script demonstrates how to change error handling - interact with MsgBox's title and text. #EndRegion - exmaple #Region @trancexx - https://www.autoitscript.com/forum/topic/154081-avoid-autoit-error-message-box-in-unknown-errors/#findComment-1111917 Func Intercept_MessageBoxW($hWnd, $sText, $sTitle, $iType) If $sTitle = 'AutoIt' Then $sTitle = 'TESTING: ' & StringReplace($sTitle, "AutoIt", @ScriptName) 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] EndFunc ;==>Intercept_MessageBoxW ; The magic is down below Func AddHookApi($sModuleName, $vFunctionName, $vNewFunction, $sRet = "", $sParams = "") Local Static $pImportDirectory, $hInstance Local Const $IMAGE_DIRECTORY_ENTRY_IMPORT = 1 If Not $pImportDirectory Then $hInstance = _WinAPI_GetModuleHandle(0) $pImportDirectory = ImageDirectoryEntryToData($hInstance, $IMAGE_DIRECTORY_ENTRY_IMPORT) If @error Then Return SetError(1, 0, 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, $pModuleName, $pFuncName 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 $pModuleName = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAModuleName") $tModuleName = DllStructCreate("char Name[" & _WinAPI_StringLenA($pModuleName) & "]", $pModuleName) 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 $pFuncName = $hInstance + $iBufferOffset2 + 2 ; 2 is size od "word", see line below... $tBuffer = DllStructCreate("word Ordinal; char Name[" & _WinAPI_StringLenA($pFuncName) & "]", $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 #Region ; the #Au3Stripper_Off/#Au3Stripper_On directives, used in this place will lead to errors as /RM is used and all variables was changed in entire script but not within this region ;~ #Au3Stripper_Off ;~ DllStructSetData($tFunctionOffset, 1, DllCallbackGetPtr(DllCallbackRegister($vNewFunction, $sRet, $sParams))) ;~ #Au3Stripper_On #EndRegion ; the #Au3Stripper_Off/#Au3Stripper_On directives, used in this place will lead to errors as /RM is used and all variables was changed in entire script but not within this region ; for this reason __AddHookApi_DllCallbackRegister_wrapper() was added and enclosed within #Au3Stripper_Off >>> #Au3Stripper_On section __AddHookApi_DllCallbackRegister_wrapper($tFunctionOffset, $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 #Au3Stripper_Off Func __AddHookApi_DllCallbackRegister_wrapper($tFunctionOffset__Wrapped, $vNewFunction__Wrapped, $sRet__Wrapped, $sParams__Wrapped) DllStructSetData($tFunctionOffset__Wrapped, 1, DllCallbackGetPtr(DllCallbackRegister($vNewFunction__Wrapped, $sRet__Wrapped, $sParams__Wrapped))) EndFunc ;==>__AddHookApi_DllCallbackRegister_wrapper #Au3Stripper_On 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 ImageDirectoryEntryToData($hInstance, $iDirectoryEntry) ; Get pointer to data Local $pPointer = $hInstance ; Start processing passed binary data. 'Reading' PE format follows. Local $tIMAGE_DOS_HEADER = DllStructCreate("char Magic[2];" & _ "word BytesOnLastPage;" & _ "word Pages;" & _ "word Relocations;" & _ "word SizeofHeader;" & _ "word MinimumExtra;" & _ "word MaximumExtra;" & _ "word SS;" & _ "word SP;" & _ "word Checksum;" & _ "word IP;" & _ "word CS;" & _ "word Relocation;" & _ "word Overlay;" & _ "char Reserved[8];" & _ "word OEMIdentifier;" & _ "word OEMInformation;" & _ "char Reserved2[20];" & _ "dword AddressOfNewExeHeader", _ $pPointer) Local $sMagic = DllStructGetData($tIMAGE_DOS_HEADER, "Magic") ; Check if it's valid format If Not ($sMagic == "MZ") Then Return SetError(1, 0, 0) ; MS-DOS header missing. Btw 'MZ' are the initials of Mark Zbikowski in case you didn't know. ; Move pointer $pPointer += DllStructGetData($tIMAGE_DOS_HEADER, "AddressOfNewExeHeader") ; move to PE file header ; In place of IMAGE_NT_SIGNATURE structure Local $tIMAGE_NT_SIGNATURE = DllStructCreate("dword Signature", $pPointer) ; Check signature If DllStructGetData($tIMAGE_NT_SIGNATURE, "Signature") <> 17744 Then ; IMAGE_NT_SIGNATURE Return SetError(2, 0, 0) ; wrong signature. For PE image should be "PE\0\0" or 17744 dword. EndIf ; Move pointer $pPointer += 4 ; size of $tIMAGE_NT_SIGNATURE structure ; In place of IMAGE_FILE_HEADER structure ; Move pointer $pPointer += 20 ; size of $tIMAGE_FILE_HEADER structure ; Determine the type Local $tMagic = DllStructCreate("word Magic;", $pPointer) Local $iMagic = DllStructGetData($tMagic, 1) Local $tIMAGE_OPTIONAL_HEADER If $iMagic = 267 Then ; x86 version ; Move pointer $pPointer += 96 ; size of $tIMAGE_OPTIONAL_HEADER ElseIf $iMagic = 523 Then ; x64 version ; Move pointer $pPointer += 112 ; size of $tIMAGE_OPTIONAL_HEADER Else Return SetError(3, 0, 0) ; unsupported module type EndIf ; Validate input by checking available number of structures that are in the module Local Const $IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16 ; predefined value that PE modules always use (AutoIt certainly) If $iDirectoryEntry > $IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1 Then Return SetError(4, 0, 0) ; invalid input ; Calculate the offset to wanted entry (every entry is 8 bytes) $pPointer += 8 * $iDirectoryEntry ; At place of correst directory entry Local $tIMAGE_DIRECTORY_ENTRY = DllStructCreate("dword VirtualAddress; dword Size", $pPointer) ; Collect data Local $pAddress = DllStructGetData($tIMAGE_DIRECTORY_ENTRY, "VirtualAddress") If $pAddress = 0 Then Return SetError(5, 0, 0) ; invalid input ; $pAddress is RVA, add it to base address Return $hInstance + $pAddress EndFunc ;==>ImageDirectoryEntryToData #EndRegion @trancexx - https://www.autoitscript.com/forum/topic/154081-avoid-autoit-error-message-box-in-unknown-errors/#findComment-1111917 Explanations: Using @trancexx code, in order to use: #AutoIt3Wrapper_Run_Au3Stripper=y #Au3Stripper_Parameters=/so /pe #AutoIt3Wrapper_Au3Stripper_OnError=f there is also a need to use: #Au3Stripper_Ignore_Funcs=Intercept_MessageBoxW Because in other way: #Au3Stripper_Parameters=/so /pe Will strip down the function as she is not called directly. Only the function name is used but as a string and not directly like a "pointer" To prevent using: #Au3Stripper_Ignore_Funcs=Intercept_MessageBoxW The Intercept_MessageBoxW can be called as a parameter for FuncName(Intercept_MessageBoxW) this way: ;~ AddHookApi("user32.dll", "MessageBoxW", "Intercept_MessageBoxW", "int", "hwnd;wstr;wstr;uint") AddHookApi("user32.dll", "MessageBoxW", FuncName(Intercept_MessageBoxW), "int", "hwnd;wstr;wstr;uint") In such case Au3Stripper knows that Intercept_MessageBoxW was used and should not be stripped. REMARK: You can also notice that I used: #Au3Stripper_Parameters=/SO /PE /RM I mean the the most demanding/restrictive option /RM For this reason this following mod was added: ..... #Region ; the #Au3Stripper_Off/#Au3Stripper_On directives, used in this place will lead to errors as /RM is used and all variables was changed in entire script but not within this region ;~ #Au3Stripper_Off ;~ DllStructSetData($tFunctionOffset, 1, DllCallbackGetPtr(DllCallbackRegister($vNewFunction, $sRet, $sParams))) ;~ #Au3Stripper_On #EndRegion ; the #Au3Stripper_Off/#Au3Stripper_On directives, used in this place will lead to errors as /RM is used and all variables was changed in entire script but not within this region ; for this reason __AddHookApi_DllCallbackRegister_wrapper() was added and enclosed within #Au3Stripper_Off >>> #Au3Stripper_On section __AddHookApi_DllCallbackRegister_wrapper($tFunctionOffset, $vNewFunction, $sRet, $sParams) ..... #Au3Stripper_Off Func __AddHookApi_DllCallbackRegister_wrapper($tFunctionOffset__Wrapped, $vNewFunction__Wrapped, $sRet__Wrapped, $sParams__Wrapped) DllStructSetData($tFunctionOffset__Wrapped, 1, DllCallbackGetPtr(DllCallbackRegister($vNewFunction__Wrapped, $sRet__Wrapped, $sParams__Wrapped))) EndFunc ;==>__AddHookApi_DllCallbackRegister_wrapper #Au3Stripper_On ..... The reason that I do not must to use: ;~ #Au3Stripper_Ignore_Funcs=__AddHookApi_DllCallbackRegister_wrapper is because __AddHookApi_DllCallbackRegister_wrapper() is used/called before the #Au3Stripper_Off / #Au3Stripper_Off sections occurs so Au3Stripper already dit the /RM action on the function name in entire script but at this moment do not touched $******__Wrapped variables. @Jos Does this example cover the whole topic of using Au3Stripper with this @trancexx script, I mean all releated with the /SO /PE /RM parameters? btw. I wonder whether, for the correctness of "code reading" and protection against possible changes in Au3Stripper, I should still use: #Au3Stripper_Ignore_Funcs=__AddHookApi_DllCallbackRegister_wrapper -
Avoid "AutoIt Error" message box in unknown errors
mLipok replied to EKY32's topic in AutoIt General Help and Support
because I inform him #Au3Stripper_Ignore_Errors_in_Funcs=AddHookApi that I have already solved the problem in this function and he should not worry about it anymore. at least this is my understanding of what #Au3Stripper_Ignore_Errors_in_Funcs should do. -
Avoid "AutoIt Error" message box in unknown errors
mLipok replied to EKY32's topic in AutoIt General Help and Support
Thanks. Now I see what is going on. the problem is related to #Au3Stripper_Parameters=/so /pe which strip down the Func Intercept_MessageBoxW($hWnd, $sText, $sTitle, $iType) If $sTitle = 'AutoIt' Then $sTitle = 'TESTING: ' & StringReplace($sTitle, "AutoIt", @ScriptName) 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] EndFunc ;==>Intercept_MessageBoxW So once what can be done is to use: #Au3Stripper_Ignore_Funcs=Intercept_MessageBoxW but still, all warnings from Au3Stripper will appear in the console window. So I also added: #Au3Stripper_Ignore_Errors_in_Funcs=AddHookApi but still, all warnings from Au3Stripper will appear in the console window. Here is modified: #Region - AutoIt3Wrapper directives section ; General section #AutoIt3Wrapper_UseX64=n #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_Compression=4 ; Au3Check section #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 6 -w 7 ; Au3Stripper section #AutoIt3Wrapper_Run_Au3Stripper=y #Au3Stripper_Parameters=/so /pe #AutoIt3Wrapper_Au3Stripper_OnError=f #Au3Stripper_Ignore_Funcs=Intercept_MessageBoxW #Au3Stripper_Ignore_Errors_in_Funcs=AddHookApi #EndRegion - AutoIt3Wrapper directives section #include <WinApi.au3> #Region - exmaple AddHookApi("user32.dll", "MessageBoxW", "Intercept_MessageBoxW", "int", "hwnd;wstr;wstr;uint") MsgBox(0, 'Test', 'Some normal MsgBox text') DllStructCreate("byte[123456789097]") ; This is a deliberate action intended to display an error, as this script demonstrates how to change error handling - interact with MsgBox's title and text. #EndRegion - exmaple #Region @trancexx - https://www.autoitscript.com/forum/topic/154081-avoid-autoit-error-message-box-in-unknown-errors/#findComment-1111917 Func Intercept_MessageBoxW($hWnd, $sText, $sTitle, $iType) If $sTitle = 'AutoIt' Then $sTitle = 'TESTING: ' & StringReplace($sTitle, "AutoIt", @ScriptName) 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] EndFunc ;==>Intercept_MessageBoxW ; The magic is down below Func AddHookApi($sModuleName, $vFunctionName, $vNewFunction, $sRet = "", $sParams = "") Local Static $pImportDirectory, $hInstance Local Const $IMAGE_DIRECTORY_ENTRY_IMPORT = 1 If Not $pImportDirectory Then $hInstance = _WinAPI_GetModuleHandle(0) $pImportDirectory = ImageDirectoryEntryToData($hInstance, $IMAGE_DIRECTORY_ENTRY_IMPORT) If @error Then Return SetError(1, 0, 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, $pModuleName, $pFuncName 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 $pModuleName = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAModuleName") $tModuleName = DllStructCreate("char Name[" & _WinAPI_StringLenA($pModuleName) & "]", $pModuleName) 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 $pFuncName = $hInstance + $iBufferOffset2 + 2 ; 2 is size od "word", see line below... $tBuffer = DllStructCreate("word Ordinal; char Name[" & _WinAPI_StringLenA($pFuncName) & "]", $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 ImageDirectoryEntryToData($hInstance, $iDirectoryEntry) ; Get pointer to data Local $pPointer = $hInstance ; Start processing passed binary data. 'Reading' PE format follows. Local $tIMAGE_DOS_HEADER = DllStructCreate("char Magic[2];" & _ "word BytesOnLastPage;" & _ "word Pages;" & _ "word Relocations;" & _ "word SizeofHeader;" & _ "word MinimumExtra;" & _ "word MaximumExtra;" & _ "word SS;" & _ "word SP;" & _ "word Checksum;" & _ "word IP;" & _ "word CS;" & _ "word Relocation;" & _ "word Overlay;" & _ "char Reserved[8];" & _ "word OEMIdentifier;" & _ "word OEMInformation;" & _ "char Reserved2[20];" & _ "dword AddressOfNewExeHeader", _ $pPointer) Local $sMagic = DllStructGetData($tIMAGE_DOS_HEADER, "Magic") ; Check if it's valid format If Not ($sMagic == "MZ") Then Return SetError(1, 0, 0) ; MS-DOS header missing. Btw 'MZ' are the initials of Mark Zbikowski in case you didn't know. ; Move pointer $pPointer += DllStructGetData($tIMAGE_DOS_HEADER, "AddressOfNewExeHeader") ; move to PE file header ; In place of IMAGE_NT_SIGNATURE structure Local $tIMAGE_NT_SIGNATURE = DllStructCreate("dword Signature", $pPointer) ; Check signature If DllStructGetData($tIMAGE_NT_SIGNATURE, "Signature") <> 17744 Then ; IMAGE_NT_SIGNATURE Return SetError(2, 0, 0) ; wrong signature. For PE image should be "PE\0\0" or 17744 dword. EndIf ; Move pointer $pPointer += 4 ; size of $tIMAGE_NT_SIGNATURE structure ; In place of IMAGE_FILE_HEADER structure ; Move pointer $pPointer += 20 ; size of $tIMAGE_FILE_HEADER structure ; Determine the type Local $tMagic = DllStructCreate("word Magic;", $pPointer) Local $iMagic = DllStructGetData($tMagic, 1) Local $tIMAGE_OPTIONAL_HEADER If $iMagic = 267 Then ; x86 version ; Move pointer $pPointer += 96 ; size of $tIMAGE_OPTIONAL_HEADER ElseIf $iMagic = 523 Then ; x64 version ; Move pointer $pPointer += 112 ; size of $tIMAGE_OPTIONAL_HEADER Else Return SetError(3, 0, 0) ; unsupported module type EndIf ; Validate input by checking available number of structures that are in the module Local Const $IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16 ; predefined value that PE modules always use (AutoIt certainly) If $iDirectoryEntry > $IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1 Then Return SetError(4, 0, 0) ; invalid input ; Calculate the offset to wanted entry (every entry is 8 bytes) $pPointer += 8 * $iDirectoryEntry ; At place of correst directory entry Local $tIMAGE_DIRECTORY_ENTRY = DllStructCreate("dword VirtualAddress; dword Size", $pPointer) ; Collect data Local $pAddress = DllStructGetData($tIMAGE_DIRECTORY_ENTRY, "VirtualAddress") If $pAddress = 0 Then Return SetError(5, 0, 0) ; invalid input ; $pAddress is RVA, add it to base address Return $hInstance + $pAddress EndFunc ;==>ImageDirectoryEntryToData #EndRegion @trancexx - https://www.autoitscript.com/forum/topic/154081-avoid-autoit-error-message-box-in-unknown-errors/#findComment-1111917 @Jos could you please take a look the above script and check why this following information still shows up in console even though I use the directive : #Au3Stripper_Ignore_Funcs=Intercept_MessageBoxW #Au3Stripper_Ignore_Errors_in_Funcs=AddHookApi -
Avoid "AutoIt Error" message box in unknown errors
mLipok replied to EKY32's topic in AutoIt General Help and Support
When you try to use: with: #AutoIt3Wrapper_Au3Stripper_OnError=c compiled version works well. but with: #AutoIt3Wrapper_Au3Stripper_OnError=f the compiled version doesn't even show the basic MsgBox , I mean this following one doesn't show up: -
I also have other question. How to connactate this following string Local $Json1 = '{"name":"John","age":30,"locations":[]}' Local $Json2 = '{"City":"Paris","Country":"France"}' Local $Json3 = '{"City":"London","Country":"England"}' to get such results: {"name":"John","age":30,"locations":[{"City":"Paris","Country":"France"},{"City":"London","Country":"England"}] The previosuly published example did similar things but as result there was "locations" as JSON_OBJECT - a dicionary element in JSON structure, but this time the "locations" it is an JSON_ARRAY - a list of elements in JSON structure
-
I have a question about this following example: #include "Json.au3" ConsoleWrite("- Test8() : " & Test8() & @CRLF) Func Test8() ; Your three JSON strings Local $Json1 = '{"name":"John","age":30,"locations":{}}' Local $Json2 = '{"MainCity":"Paris","MainCountry":"France"}' Local $Json3 = '{"City":"London","Country":"England"}' ; Decode Local $obj1 = Json_Decode($Json1) Local $obj2 = Json_Decode($Json2) Local $obj2a = $obj2 Local $obj3 = Json_Decode($Json3) ; Insert obj2 into obj1 under a key (e.g. "location") $obj1.Item("locations") = $obj2 ; <-- This puts data into object $obj1.Item("locations").Item("location1") = $obj2a ; <-- This creates a sub-object $obj1.Item("locations").Item("location2") = $obj3 ; <-- This creates a sub-object ; Encode back to JSON Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) ConsoleWrite($final & @CRLF) EndFunc ;==>Test8 Why I can't use $obj2a in the same way as I used $obj3. I know I already used $obj2 but why I can't use them again ? I know that I can use them like this: ;~ $obj1.Item("locations") = $obj2 ; <-- This puts data into object $obj1.Item("locations").Item("location1") = $obj2a ; <-- This creates a sub-object But why can't use them together ?
-
Sorry, the newer version works.
-
Avoid "AutoIt Error" message box in unknown errors
mLipok replied to EKY32's topic in AutoIt General Help and Support
I know, I know. You need a simple example that clearly demonstrates what's going on with a very short description of the problem. So you rightly expect (as usual) that the person requesting help will put in the effort to prepare a question and test cases that clearly and concisely demonstrate what's wrong. I'll try to prepare that in the coming days - at least I hope so. -
Avoid "AutoIt Error" message box in unknown errors
mLipok replied to EKY32's topic in AutoIt General Help and Support
Sitll we are not talking about the fact that AutoIt crashes. We are talking about: Why @trancexx code is not working in 64bit.