I made it work, only issue currently is IUnknown.Release is called on my object 3 or 1 time(s), depending if the object is used or not before calling $IRunningObjectTable.Revoke.
I suspect this may be an error in my custom object returned from IDispatch().
If not i will look into the other interfaces requested when calling IUnknown.QueryInterface
I will post the functional code in this post when i get home later today and can access my code.
#include <WinAPIDiag.au3>
#include "..\AutoItObject_Internal.au3"
$IID_IRunningObjectTable = "{00000010-0000-0000-C000-000000000046}"
$IID_IMoniker = "{0000000f-0000-0000-C000-000000000046}"
$AutoItError = ObjEvent("AutoIt.Error", "ErrFunc") ; Install a custom error handler
Func ErrFunc($oError)
ConsoleWrite("!>COM Error !"&@CRLF&"!>"&@TAB&"Number: "&Hex($oError.Number,8)&@CRLF&"!>"&@TAB&"Windescription: "&StringRegExpReplace($oError.windescription,"\R$","")&@CRLF&"!>"&@TAB&"Source: "&$oError.source&@CRLF&"!>"&@TAB&"Description: "&$oError.description&@CRLF&"!>"&@TAB&"Helpfile: "&$oError.helpfile&@CRLF&"!>"&@TAB&"Helpcontext: "&$oError.helpcontext&@CRLF&"!>"&@TAB&"Lastdllerror: "&$oError.lastdllerror&@CRLF&"!>"&@TAB&"Scriptline: "&$oError.scriptline&@CRLF)
EndFunc ;==>ErrFunc
$IDispatch = IDispatch()
$IDispatch.name = "my name is Danny"
$IRunningObjectTable = DllCall("Ole32.dll","LONG","GetRunningObjectTable","DWORD",0,"PTR*",0)
If @error<>0 Then Exit MsgBox(0, @ScriptLineNumber, @error)
$IRunningObjectTable = ObjCreateInterface($IRunningObjectTable[2],$IID_IRunningObjectTable,"Register HRESULT(DWORD;PTR;PTR;DWORD*);Revoke HRESULT(DWORD);IsRunning HRESULT(PTR*);GetObject HRESULT(PTR;PTR*);NoteChangeTime HRESULT(DWORD;PTR*);GetTimeOfLastChange HRESULT(PTR*;PTR*);EnumRunning HRESULT(PTR*);",True)
If @error<>0 Then Exit MsgBox(0, @ScriptLineNumber, @error)
$sCLSID="AutoIt.COMDemo"
$IMoniker=DllCall("Ole32.dll", "LONG", "CreateFileMoniker", "WSTR", $sCLSID, "PTR*", 0)
If @error<>0 Then Exit MsgBox(0, @ScriptLineNumber, @error)
Global Const $ROTFLAGS_REGISTRATIONKEEPSALIVE=0x01
Global Const $ROTFLAGS_ALLOWANYCLIENT=0x02
AddRef(Ptr($IDispatch))
$dwRegister=0
$r=$IRunningObjectTable.Register( 0, ptr($IDispatch), $IMoniker[2], $dwRegister )
If @error<>0 Then Exit 1
If $dwRegister=0 Then
MsgBox(0, "", _WinAPI_GetErrorMessage($r))
Exit 2
EndIf
$IMoniker = ObjCreateInterface($IMoniker[2], $IID_IMoniker)
AddRef(Ptr($IDispatch))
AddRef(Ptr($IDispatch))
AddRef(Ptr($IDispatch));TODO: look into RunningObjectTable calling IUnknown:Release 3 times if used one or more times, but only once if not used before release @.@
$IMoniker=0
$IRunningObjectTable=0
Opt("GuiOnEventMode", 1)
$hWnd=GUICreate("Title",700,320)
GUISetState(@SW_SHOW,$hWnd)
GUISetOnEvent(-3, "_MyExit", $hWnd)
While 1
Sleep(10)
WEnd
Func _MyExit()
Local $IRunningObjectTable = DllCall("Ole32.dll","LONG","GetRunningObjectTable","DWORD",0,"PTR*",0)
If @error<>0 Then Exit MsgBox(0, @ScriptLineNumber, @error)
$IRunningObjectTable = ObjCreateInterface($IRunningObjectTable[2],$IID_IRunningObjectTable,"Register HRESULT(DWORD;PTR;PTR;DWORD*);Revoke HRESULT(DWORD);IsRunning HRESULT(PTR*);GetObject HRESULT(PTR*;PTR**);NoteChangeTime HRESULT(DWORD;PTR*);GetTimeOfLastChange HRESULT(PTR*;PTR*);EnumRunning HRESULT(PTR*);",True)
If @error<>0 Then Exit MsgBox(0, @ScriptLineNumber, @error)
$IRunningObjectTable.Revoke($dwRegister)
ConsoleWrite("IRunningObjectTable.Revoke"&@CRLF)
$IRunningObjectTable=0
$IDispatch=0
Exit
EndFunc
AutoItObject_Internal.au3
Files to test while the script is running
test.vbs
com.php
Change first parameter in IRunningObjectTable.Register to $ROTFLAGS_REGISTRATIONKEEPSALIVE and the object won't be released from the ROT until IRunningObjectTable.Revoke is called