Danyfirex Posted February 23, 2021 Share Posted February 23, 2021 Hello @jugador I hadn't had time to review. Are you trying to read from AutoIt script instead using Excel? If It's so You could do it these way. It's a little messed but you can clear it. expandcollapse popup#AutoIt3Wrapper_UseX64=N #include <AutoItConstants.au3> #include <WinAPI.au3> #include <array.au3> #include ".\Includes\AccVarsUtilities.au3" Global Const $sCLSID_App = "{86541CE9-EA39-4175-B37A-FDAE655AD30C}" Global Const $sIID_IScripRTD = "{EC0E6191-DB51-11D3-8F3E-00C04F3651B8}" Global Const $sIID_IRTDUpdateEvent = "{A43788C1-D91B-11D3-8F39-00C04F3651B8}" Global Const $tagIUnknown = "QueryInterface hresult(ptr;ptr*);" & _ "AddRef dword();" & _ "Release dword();" Global Const $tagIDispatch = $tagIUnknown & _ "GetTypeInfoCount hresult(dword*);" & _ "GetTypeInfo hresult(dword;dword;ptr*);" & _ "GetIDsOfNames hresult(struct*;struct*;dword;dword;struct*);" & _ "Invoke hresult(uint;struct*;dword;word;struct*;struct*;ptr;uint*);" Global Const $tagIScripRTD = $tagIDispatch & _ "ServerStart hresult(ptr;long*);" & _ "ConnectData hresult(long;ptr*;bool*;variant*);" & _ "RefreshData hresult(long*;ptr*);" & _ "DisconnectData hresult(long);" & _ "Heartbeat hresult(long*);" & _ "ServerTerminate hresult();" Global Const $tag_IRTDUpdateEvent = $tagIDispatch & _ "UpdateNotify hresult();" & _ "get_HeartbeatInterval hresult(long);" & _ "put_HeartbeatInterval hresult(long*);" & _ "Disconnect hresult();" Global Const $sIID_IUnknown = "{00000000-0000-0000-C000-000000000046}" Global $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc") Global $g_oApp_ObjCast=0 _Test() Func _Test() Local $oApp_Obj = ObjCreateInterface($sCLSID_App, $sIID_IScripRTD) ConsoleWrite("IsObj($oApp_Obj): " & IsObj($oApp_Obj) & @CRLF) $g_oApp_ObjCast = ObjCreateInterface($oApp_Obj, $sIID_IScripRTD, $tagIScripRTD, False) ConsoleWrite("IsObj($g_oApp_ObjCast): " & IsObj($g_oApp_ObjCast) & @CRLF) Local $tIRTDUpdateEvents Local $ooIRTDUpdateEvents = ObjectFromTag("IRTDUpdateEvent_", $tag_IRTDUpdateEvent, $tIRTDUpdateEvents, False, False, $sIID_IRTDUpdateEvent) ConsoleWrite("IsObj($ooIRTDUpdateEvents): " & IsObj($ooIRTDUpdateEvents) & @CRLF) Local $pooIRTDUpdateEvents = $ooIRTDUpdateEvents() ConsoleWrite("$iHeartbeat: " & $oApp_Obj.Heartbeat() & @CRLF) Local $iHeartbeat = 0 $g_oApp_ObjCast.Heartbeat($iHeartbeat) ConsoleWrite("$iHeartbeat: " & $iHeartbeat & @CRLF) Local $iServerStatus = 0 ;~ $oApp_Obj.ServerStart($prt_IUnknown) ;this will fail $g_oApp_ObjCast.ServerStart($pooIRTDUpdateEvents, $iServerStatus) ConsoleWrite("$iHeartbeat: " & $iHeartbeat & @CRLF) Local $iTopidId = 0 Local $aStrings[] = ["test"] Local $pSafeArrayStrings AccVars_ArrayToSafeArray($aStrings, $pSafeArrayStrings) Local $bBool = True Local $aVariant = 0 $g_oApp_ObjCast.ConnectData($iTopidId, $pSafeArrayStrings, $bBool, $aVariant) ConsoleWrite("$iTopidId: " & $iTopidId & @CRLF) ConsoleWrite("$aStrings: " & IsArray($aStrings) & @CRLF) ConsoleWrite("$bBool: " & $bBool & @CRLF) ConsoleWrite("$aVariant: " & $aVariant & @CRLF) Local $aStringsData[0] Local $pSafeArrayData While Sleep(30) ;~ AccVars_ArrayToSafeArray($aStringsData, $pSafeArrayData) ;~ $g_oApp_ObjCast.RefreshData($iTopidId, $pSafeArrayData) ;~ AccVars_SafeArrayToArray($pSafeArrayData, $aStringsData) ;~ _ArrayDisplay($aStringsData) WEnd EndFunc ;==>_Test ;;============= Func IRTDUpdateEvent_UpdateNotify($pSelf) ConsoleWrite('> UpdateNotify: ' & @CRLF) Local $aStringsData[0] Local $pSafeArrayData AccVars_ArrayToSafeArray($aStringsData, $pSafeArrayData) $g_oApp_ObjCast.RefreshData(0, $pSafeArrayData) AccVars_SafeArrayToArray($pSafeArrayData, $aStringsData) ConsoleWrite(_ArrayToString($aStringsData) & @CRLF) Return $S_OK EndFunc ;==>IRTDUpdateEvent_UpdateNotify Func IRTDUpdateEvent_GetHeartbeatInterval($pSelf, $pvalue) Local $S_result = 0 ConsoleWrite('> $S_result: ' & $S_result & @CRLF) Return $S_result EndFunc ;==>IRTDUpdateEvent_GetHeartbeatInterval Func IRTDUpdateEvent_PutHeartbeatInterval($pSelf, $pvalue) ConsoleWrite('> $pvalue: ' & $pvalue & @CRLF) Return $S_OK EndFunc ;==>IRTDUpdateEvent_PutHeartbeatInterval Func IRTDUpdateEvent_Disconnect($pSelf) Return $S_OK EndFunc ;==>IRTDUpdateEvent_Disconnect Func IRTDUpdateEvent_QueryInterface($pSelf, $pRIID, $pObj) Local $sIID = StringFromGUID($pRIID) If $sIID = $sIID_IUnknown Then DllStructSetData(DllStructCreate("ptr", $pObj), 1, $pSelf) Return $S_OK ElseIf $sIID = $sIID_IRTDUpdateEvent Then DllStructSetData(DllStructCreate("ptr", $pObj), 1, $pSelf) Return $S_OK Else Return $E_NOINTERFACE EndIf EndFunc ;==>IRTDUpdateEvent_QueryInterface Func IRTDUpdateEvent_AddRef($pSelf) ConsoleWrite('> AddRef: ' & @CRLF) Return 1 EndFunc ;==>IRTDUpdateEvent_AddRef Func IRTDUpdateEvent_Release($pSelf) ConsoleWrite('> Release: ' & @CRLF) Return 1 EndFunc ;==>IRTDUpdateEvent_Release ;;============= Func IRTDUpdateEvent_GetTypeInfoCount($pSelf) ; Ret: long Par: ptr EndFunc ;==>IRTDUpdateEvent_GetTypeInfoCount Func IRTDUpdateEvent_GetTypeInfo($pSelf) ; Ret: long Par: dword;dword;ptr EndFunc ;==>IRTDUpdateEvent_GetTypeInfo Func IRTDUpdateEvent_GetIDsOfNames($pSelf) ; Ret: long Par: ptr;ptr;dword;dword;ptr EndFunc ;==>IRTDUpdateEvent_GetIDsOfNames Func IRTDUpdateEvent_Invoke($pSelf) ; Ret: long Par: uint;ptr;dword;word;ptr;ptr;ptr;ptr EndFunc ;==>IRTDUpdateEvent_Invoke Func StringFromGUID($pGUID) Local $aResult = DllCall("ole32.dll", "int", "StringFromGUID2", "struct*", $pGUID, "wstr", "", "int", 40) If @error Then Return SetError(@error, @extended, "") Return SetExtended($aResult[0], $aResult[2]) EndFunc ;==>StringFromGUID ;;-------- ;;-------- 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 ;;-------- ; #FUNCTION# ============================================================================= ; Name...........: _ErrFunc() ; ======================================================================================== ; User's COM error function. Will be called if COM error occurs #forceref $oErrorHandler Func _ErrFunc($oError) ; Do anything here. ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _ @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _ @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _ @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _ @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _ @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _ @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _ @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _ @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _ @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF) EndFunc ;==>_ErrFunc PD: Make sure to add #include ".\Includes\AccVarsUtilities.au3" It's from our dear user @LarsJ from here. Saludos LarsJ, jugador and junkew 3 Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
jugador Posted February 24, 2021 Author Share Posted February 24, 2021 (edited) On 2/23/2021 at 10:47 PM, Danyfirex said: Are you trying to read from AutoIt script instead using Excel? Yes. @Danyfirex Thank You. Tested on two different server and it work. @wolf9228 also posted example on Exe server but it’s too complicated for me to understand. https://www.autoitscript.com/forum/topic/157680-exe-server-idispatch-call/ @Danyfirex for knowledge what is this IRTDUpdateEvent* callback ..... is it Object/ptr/or something else because none of this work $ooIRTDUpdateEvents / $pooIRTDUpdateEvents with ServerStart method when calling without using Superposed technique ( $g_oApp_ObjCast ) => getting error Type mismatch VarGetType($ooIRTDUpdateEvents) ==> Object VarGetType($pooIRTDUpdateEvents) ==> Int32 Again Thank you @Danyfirex for your time & the solution.😊 Edited March 11, 2021 by jugador 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