Leaderboard
Popular Content
Showing content with the highest reputation on 10/31/2021 in all areas
-
try adding this lines at the beginning of your script: #include <WinAPIFiles.au3> ;Turn off redirection for a 32-bit script on 64-bit system. If @OSArch = "X64" And Not @AutoItX64 Then _WinAPI_Wow64EnableWow64FsRedirection(False)2 points
-
AutoIt Snippets
CarlD reacted to JockoDundee for a topic
1 point -
Aut2exe : Error copying source to destination file when compiling ?
TheDcoder reacted to JockoDundee for a topic
1 point -
AutoIt Snippets
CarlD reacted to JockoDundee for a topic
@CarlD, yes but what happens if the string to write and erase is also a valid integer, say 999999999 or 000001 ?1 point -
Aut2exe : Error copying source to destination file when compiling ?
TheDcoder reacted to JockoDundee for a topic
1 point -
This is a new version of the server/client example above based on the FakeObj object. Again, FakeObj is passed to the client through a ROT-object. Here, FakeObj can handle strings, doubles, integers and arrays. Server.au3: #AutoIt3Wrapper_Au3Check_Parameters=-d -w- 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=Y Opt( "MustDeclareVars", 1 ) #include <Array.au3> #include "AccVars.au3" #include "IRunningObjectTable.au3" Global $oError = ObjEvent("AutoIt.Error", "_ErrFunc") Example() Func Example() ConsoleWrite( "Code running on server ..." & @CRLF ) Local $tFakeObj, $oFakeObj $oFakeObj = _ObjectFromTag("__MyInterface_", "Data hresult(variant)", $tFakeObj) $oFakeObj.Data("Test string from Server .....") $oFakeObj.Data( 123.123 ) $oFakeObj.Data( 123 ) Local $aArray = [ 123, 123.123, "Server test string" ] $oFakeObj.Data( $aArray ) ; Create a default ROT-object (Dictionary object) Local $sDataTransferObject, $oDataTransferObject $oDataTransferObject = ROT_CreateDefaultObject( $sDataTransferObject ) ; Create Dictionary object Local $oDict = ObjCreate( "Scripting.Dictionary" ) $oDict.Item( "$oFakeObj" ) = $oFakeObj ; Add Dictionary object to ROT-object $oDataTransferObject.Add( "$oDict", $oDict ) ; Start the client script in a new process ConsoleWrite( @CRLF & "Code running on Client ..." & @CRLF ) RunWait( @AutoItExe & " /AutoIt3ExecuteScript Client.au3" & " " & $sDataTransferObject ) EndFunc Func __MyInterface_QueryInterface($pSelf, $pRIID, $pObj) Local $tStruct = DllStructCreate("ptr", $pObj) DllStructSetData($tStruct, 1, $pSelf) Return 0 ; $S_OK #forceref $pRIID EndFunc Func __MyInterface_AddRef($pSelf) Return 1 #forceref $pSelf EndFunc Func __MyInterface_Release($pSelf) Return 1 #forceref $pSelf EndFunc Func __MyInterface_Data($pSelf, $pVariant) ConsoleWrite( @CRLF & "$pVar = " & $pVariant & @CRLF ) Local $tVariant = DllStructCreate( $tagVARIANT, $pVariant ) Local $sAlign1 = " " & ( @AutoItX64 ? " " : "" ) Local $iVariantType = DllStructGetData( $tVariant, "vt" ) ConsoleWrite( "Type = 0x" & Hex( $iVariantType, 4 ) & " " & $sAlign1 ) ; 4 word elements before the data element = 8 bytes Local $pData = $pVariant + 8, $tPtr, $pPtr Switch $iVariantType Case $VT_I4 ; 4 bytes signed integer ConsoleWrite( "(VT_I4, 4 bytes signed integer)" & @CRLF ) ; The data element contains the integer in the 4 first bytes Local $tInt = DllStructCreate( "int", $pData ) Local $iInt = DllStructGetData( $tInt, 1 ) ConsoleWrite( "data = " & $iInt & @CRLF ) Case $VT_R8 ; 8 bytes double ConsoleWrite( "(VT_R8, 8 bytes double)" & @CRLF ) ; The data element contains the double in the 8 first bytes ; That's the entire data element on 32 bit and half the data element on 64 bit Local $tFlt = DllStructCreate( "double", $pData ) Local $fFlt = DllStructGetData( $tFlt, 1 ) ConsoleWrite( "data = " & $fFlt & @CRLF ) Case $VT_BSTR ; Basic string ConsoleWrite( "(VT_BSTR, basic string)" & @CRLF ) ; The data element contains a pointer to the BSTR $tPtr = DllStructCreate( "ptr", $pData ) $pPtr = DllStructGetData( $tPtr, 1 ) ConsoleWrite( "pBSTR = " & $pPtr & " (BSTR pointer)" & @CRLF ) ; The BSTR must be read with a proper BSTR-function (see Variant.au3) Local $sStr = SysReadString( $pPtr ) ConsoleWrite( "data = " & $sStr & @CRLF ) Case $VT_ARRAY + $VT_VARIANT ; Array of variants ConsoleWrite( "(VT_ARRAY+VT_VARIANT, array of variants, safearray)" & @CRLF ) ; The data element contains a pointer to the safearray in the 4/8 first bytes $tPtr = DllStructCreate( "ptr", $pData ) $pPtr = DllStructGetData( $tPtr, 1 ) ConsoleWrite( "data = " & $pPtr & " (pointer to safearray)" & @CRLF ) ; Print safearray data to console ConsoleWrite( @CRLF & "Safearray data:" & @CRLF ) PrintSafeArray1D( $pPtr ) ; Convert safearray to AutoIt array through internal COM conversions ; Display the AutoIt array with _ArrayDisplay( $aArray ) ConsoleWrite( @CRLF & "Convert safearray to AutoIt array" & @CRLF ) Local $aArray SafeArrayLock( $pPtr ) AccessVariables02( AccVars_SafeArrayToArray, $pPtr, $aArray ) SafeArrayUnlock( $pPtr ) ConsoleWrite( "_ArrayDisplay( <AutoIt array> ) ..." & @CRLF ) _ArrayDisplay( $aArray ) Case Else ConsoleWrite( "Variant type = " & DllStructGetData( $tVariant, "vt" ) & @CRLF ) ConsoleWrite( "Unhandled variant type" & @CRLF ) EndSwitch Return 0 ; $S_OK #forceref $pSelf EndFunc ; #FUNCTION# ============================================================================= ; Name...........: _ObjectFromTag ; ======================================================================================== Func _ObjectFromTag($sFunctionPrefix, $tagInterface, ByRef $tInterface, $fPrint = False, $bIsUnknown = Default, $sIID = "{00000000-0000-0000-C000-000000000046}") ; last param is IID_IUnknown by default If $bIsUnknown = Default Then $bIsUnknown = True Local $sInterface = $tagInterface ; copy interface description Local $tagIUnknown = "QueryInterface hresult(ptr;ptr*);" & _ "AddRef dword();" & _ "Release dword();" ; Adding IUnknown methods If $bIsUnknown Then $tagInterface = $tagIUnknown & $tagInterface ; Below line is really simple even though it looks super complex. It's just written weird to fit in one line, not to steal your attention Local $aMethods = StringSplit(StringReplace(StringReplace(StringReplace(StringReplace(StringTrimRight(StringReplace(StringRegExpReplace(StringRegExpReplace($tagInterface, "\w+\*", "ptr"), "\h*(\w+)\h*(\w+\*?)\h*(\((.*?)\))\h*(;|;*\z)", "$1\|$2;$4" & @LF), ";" & @LF, @LF), 1), "object", "idispatch"), "hresult", "long"), "bstr", "ptr"), "variant", "ptr"), @LF, 3) Local $iUbound = UBound($aMethods) Local $sMethod, $aSplit, $sNamePart, $aTagPart, $sTagPart, $sRet, $sParams, $hCallback ; Allocation $tInterface = DllStructCreate("int RefCount;int Size;ptr Object;ptr Methods[" & $iUbound & "];int_ptr Callbacks[" & $iUbound & "];ulong_ptr Slots[16]") ; 16 pointer sized elements more to create space for possible private props If @error Then Return SetError(1, 0, 0) For $i = 0 To $iUbound - 1 $aSplit = StringSplit($aMethods[$i], "|", 2) If UBound($aSplit) <> 2 Then ReDim $aSplit[2] $sNamePart = $aSplit[0] $sTagPart = $aSplit[1] $sMethod = $sFunctionPrefix & $sNamePart If $fPrint Then Local $iPar = StringInStr($sTagPart, ";", 2), $t If $iPar Then $t = "Ret: " & StringLeft($sTagPart, $iPar - 1) & " " & _ "Par: " & StringRight($sTagPart, StringLen($sTagPart) - $iPar) Else $t = "Ret: " & $sTagPart EndIf Local $s = "Func " & $sMethod & _ "( $pSelf ) ; " & $t & @CRLF & _ "EndFunc" & @CRLF ConsoleWrite($s) EndIf $aTagPart = StringSplit($sTagPart, ";", 2) $sRet = $aTagPart[0] $sParams = StringReplace($sTagPart, $sRet, "", 1) $sParams = "ptr" & $sParams $hCallback = DllCallbackRegister($sMethod, $sRet, $sParams) If @error Then ConsoleWrite('! ' & @error & ' ' & $sMethod & @CRLF & @CRLF) EndIf DllStructSetData($tInterface, "Methods", DllCallbackGetPtr($hCallback), $i + 1) ; save callback pointer DllStructSetData($tInterface, "Callbacks", $hCallback, $i + 1) ; save callback handle Next DllStructSetData($tInterface, "RefCount", 1) ; initial ref count is 1 DllStructSetData($tInterface, "Size", $iUbound) ; number of interface methods DllStructSetData($tInterface, "Object", DllStructGetPtr($tInterface, "Methods")) ; Interface method pointers Return ObjCreateInterface(DllStructGetPtr($tInterface, "Object"), $sIID, $sInterface, $bIsUnknown) ; pointer that's wrapped into object EndFunc ;==>ObjectFromTag Func _ErrFunc() ConsoleWrite("! COM Error ! Number: 0x" & Hex($oError.number, 8) & " ScriptLine: " & $oError.scriptline & " - " & $oError.windescription & @CRLF) Return EndFunc ;==>_ErrFunc Func PrintSafeArray1D( $pSafeArray ) If Not IsPtr( $pSafeArray ) Then Return SetError(1,0,0) If Not SafeArrayGetDim( $pSafeArray ) = 1 Then Return SetError(2,0,0) Local $tSafeArray = DllStructCreate( $tagSAFEARRAY, $pSafeArray ) Local $iElemSize = DllStructGetData( $tSAFEARRAY, "cbElements" ) Local $iUBound, $pSafeArrayData, $vt, $data SafeArrayGetUBound( $pSafeArray, 1, $iUBound ) SafeArrayAccessData( $pSafeArray, $pSafeArrayData ) For $i = 0 To $iUBound $vt = DllStructGetData( DllStructCreate( "word", $pSafeArrayData ), 1 ) Switch $vt Case $VT_I4 ; 4 bytes signed integer $data = DllStructGetData( DllStructCreate( "int", $pSafeArrayData + 8 ), 1 ) Case $VT_R8 ; 8 bytes double $data = DllStructGetData( DllStructCreate( "double", $pSafeArrayData + 8 ), 1 ) Case $VT_BSTR ; Basic string $data = SysReadString( DllStructGetData( DllStructCreate( "ptr", $pSafeArrayData + 8 ), 1 ) ) Case Else $data = "" EndSwitch ConsoleWrite( $data & @CRLF ) $pSafeArrayData += $iElemSize Next SafeArrayUnaccessData( $pSafeArray ) EndFunc Func AccVars_SafeArrayToArray( $pvSafeArray, $pArray ) ; <<<< On function entry the native AutoIt array is converted to a safearray contained in a variant >>>> ; --- Get safearray information --- ; $pvSafeArray is a variant that contains a pointer Local $pSafeArray = DllStructGetData( DllStructCreate( "ptr", $pvSafeArray + 8 ), 1 ) ; Array type Local $iVarType SafeArrayGetVartype( $pSafeArray, $iVarType ) Switch $iVarType Case $VT_I2, $VT_I4 ; Signed integers Case $VT_R4, $VT_R8 ; 4/8 bytes floats Case $VT_BSTR ; Basic string Case $VT_BOOL ; Boolean Case $VT_UI4, $VT_UI8 ; 4/8 bytes unsigned integers Case $VT_VARIANT ; Variant Case Else Return SetError(1,0,0) EndSwitch ; --- Set $pArray to match an array --- ; Set vt element to $VT_ARRAY + $iVarType DllStructSetData( DllStructCreate( "word", $pArray ), 1, $VT_ARRAY + $iVarType ) ; Set data element to safearray pointer DllStructSetData( DllStructCreate( "ptr", $pArray + 8 ), 1, $pSafeArray ) ; <<<< On function exit the safearray contained in a variant is converted to a native AutoIt array >>>> EndFunc Client.au3: #AutoIt3Wrapper_Au3Check_Parameters=-d -w- 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=Y Opt( "MustDeclareVars", 1 ) Example() Func Example() ; Get default ROT-object (Dictionary object) Local $oDataTransferObject = ObjGet( $CmdLine[1] ) ; Get Dictionary object from ROT-object Local $oDict = $oDataTransferObject.Item( "$oDict" ) Local $oFakeObj = $oDict.Item( "$oFakeObj" ) $oFakeObj.Data("Test string from Client .....") $oFakeObj.Data( 123.123 ) $oFakeObj.Data( 123 ) Local $aArray = [ 123, 123.123, "Client test string" ] $oFakeObj.Data( $aArray ) EndFunc Run Server.au3. Output in SciTE console: Code running on server ... $pVar = 0x000000000045ED30 Type = 0x0008 (VT_BSTR, basic string) pBSTR = 0x0000000000928EE8 (BSTR pointer) data = Test string from Server ..... $pVar = 0x000000000045ED30 Type = 0x0005 (VT_R8, 8 bytes double) data = 123.123 $pVar = 0x000000000045ED30 Type = 0x0003 (VT_I4, 4 bytes signed integer) data = 123 $pVar = 0x000000000045ED30 Type = 0x200C (VT_ARRAY+VT_VARIANT, array of variants, safearray) data = 0x000000000095C7B0 (pointer to safearray) Safearray data: 123 123.123 Server test string Convert safearray to AutoIt array _ArrayDisplay( <AutoIt array> ) ... Code running on Client ... $pVar = 0x000000000045E520 Type = 0x0008 (VT_BSTR, basic string) pBSTR = 0x0000000000926908 (BSTR pointer) data = Test string from Client ..... $pVar = 0x000000000045E520 Type = 0x0005 (VT_R8, 8 bytes double) data = 123.123 $pVar = 0x000000000045E520 Type = 0x0003 (VT_I4, 4 bytes signed integer) data = 123 $pVar = 0x000000000045E520 Type = 0x200C (VT_ARRAY+VT_VARIANT, array of variants, safearray) data = 0x000000000095E8F0 (pointer to safearray) Safearray data: 123 123.123 Client test string Convert safearray to AutoIt array _ArrayDisplay( <AutoIt array> ) ... All code in the 7z-file. FakeObj2.7z1 point