GetActiveObjects
Posted: 19 Aug 2020, 03:28
Not sure if this is the right section. Anyone happen to have the v2 version of this function? I've tried porting it basing on the v2 documentation but I'm not sure how the DllCalls work themselves so I'm not sure what I am doing wrong or perhaps an alternative to fetching all active specific COM objects of a certain type in v2.
v1 Original:
v2 Attempt:
v1 Original:
Code: Select all
GetActiveObjects(Prefix:="",CaseSensitive:=false) {
objects := {}
DllCall("ole32\CoGetMalloc", "uint", 1, "ptr*", malloc) ; malloc: IMalloc
DllCall("ole32\CreateBindCtx", "uint", 0, "ptr*", bindCtx) ; bindCtx: IBindCtx
DllCall(NumGet(NumGet(bindCtx+0)+8*A_PtrSize), "ptr", bindCtx, "ptr*", rot) ; rot: IRunningObjectTable
DllCall(NumGet(NumGet(rot+0)+9*A_PtrSize), "ptr", rot, "ptr*", enum) ; enum: IEnumMoniker
while DllCall(NumGet(NumGet(enum+0)+3*A_PtrSize), "ptr", enum, "uint", 1, "ptr*", mon, "ptr", 0) = 0 ; mon: IMoniker
{
DllCall(NumGet(NumGet(mon+0)+20*A_PtrSize), "ptr", mon, "ptr", bindCtx, "ptr", 0, "ptr*", pname) ; GetDisplayName
name := StrGet(pname, "UTF-16")
DllCall(NumGet(NumGet(malloc+0)+5*A_PtrSize), "ptr", malloc, "ptr", pname) ; Free
if InStr(name, Prefix, CaseSensitive) = 1 {
DllCall(NumGet(NumGet(rot+0)+6*A_PtrSize), "ptr", rot, "ptr", mon, "ptr*", punk) ; GetObject
; Wrap the pointer as IDispatch if available, otherwise as IUnknown.
if (pdsp := ComObjQuery(punk, "{00020400-0000-0000-C000-000000000046}"))
obj := ComObject(9, pdsp, 1), ObjRelease(punk)
else
obj := ComObject(13, punk, 1)
; Store it in the return array by suffix.
objects[SubStr(name, StrLen(Prefix) + 1)] := obj
}
ObjRelease(mon)
}
ObjRelease(enum)
ObjRelease(rot)
ObjRelease(bindCtx)
ObjRelease(malloc)
return objects
}
Code: Select all
GetActiveObjects(Prefix:="",CaseSensitive:=false) {
objects := {}
malloc := DllCall("ole32\CoGetMalloc", "uint", 1, "Cdecl ptr*") ; malloc: IMalloc
bindCtx := DllCall("ole32\CreateBindCtx", "uint", 0, "Cdecl ptr*", ) ; bindCtx: IBindCtx
rot := DllCall(NumGet(NumGet(bindCtx+0, "UPtr")+8*A_PtrSize, "UPtr"), "ptr", bindCtx, "Cdecl ptr*") ; rot: IRunningObjectTable
enum := DllCall(NumGet(NumGet(rot+0, "UPtr")+9*A_PtrSize, "UPtr"), "ptr", rot, "Cdecl ptr*") ; enum: IEnumMoniker
mon := DllCall(NumGet(NumGet(enum+0, "UPtr")+3*A_PtrSize, "UPtr"), "ptr", enum, "uint", 1, "ptr*", mon, "ptr", 0)
While mon = 0 ; mon: IMoniker
{
pname := DllCall(NumGet(NumGet(mon+0, "UPtr")+20*A_PtrSize, "UPtr"), "ptr", mon, "ptr", bindCtx, "ptr", 0, "Cdecl ptr*") ; GetDisplayName
name := StrGet(pname, "UTF-16")
DllCall(NumGet(NumGet(malloc+0, "UPtr")+5*A_PtrSize, "UPtr"), "ptr", malloc, "ptr", pname) ; Free
If InStr(name, Prefix, CaseSensitive) = 1 {
punk := DllCall(NumGet(NumGet(rot+0, "UPtr")+6*A_PtrSize, "UPtr"), "ptr", rot, "ptr", mon, "Cdecl ptr*") ; GetObject
; Wrap the pointer as IDispatch If available, otherwise as IUnknown.
If (pdsp := ComObjQuery(punk, "{00020400-0000-0000-C000-000000000046}"))
obj := ComObject(9, pdsp, 1), ObjRelease(punk)
Else
obj := ComObject(13, punk, 1)
; Store it in the Return array by suffix.
objects[SubStr(name, StrLen(Prefix) + 1)] := obj
}
ObjRelease(mon)
}
ObjRelease(enum)
ObjRelease(rot)
ObjRelease(bindCtx)
ObjRelease(malloc)
Return objects
}