I would like to access COM objects for applications that are not Microsoft Office or standard apps like IE. I assume I could find an API, data-dictionary, or something similar to a software dev kit. But I'm wondering if there is a way to search through the Component Services and find what objects are available. Or, search out a DLL?
-Ryan
COM access to non-Microsoft applications
Re: COM access to non-Microsoft applications
Take a look here:
GetActiveObjects - Get multiple active COM objects
https://autohotkey.com/boards/viewtopic.php?t=6494
GetActiveObjects - Get multiple active COM objects
https://autohotkey.com/boards/viewtopic.php?t=6494
Re: COM access to non-Microsoft applications
Let's see how this goes.
Re: COM access to non-Microsoft applications
Xtra, have you seen this work before? I imagine that you have. I'm not sure how the Prefix parameter works out. The application I'm using isn't an office product but is some other software. I imagine that it works something like below, but I certain that I'm wrong:
Code: Select all
activeWindow:= GetActiveObjects(My.Application)
MsgBox %activeWindow
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
}
Re: COM access to non-Microsoft applications
Try using Lexikos' example:
Code: Select all
for name, obj in GetActiveObjects()
list .= name " -- " ComObjType(obj, "Name") "`n"
MsgBox %list%
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
}
Re: COM access to non-Microsoft applications
Perhaps I'm not familiar enough with COM to understand what the output of the MsgBox is saying:
I'm seeing a bunch of hexadecimal values and "--INoteLinkContentService"
hexadecimal"--INoteLinkContentService"
!Personal-Monikers::FileSyncClient -- IFileSyncClient9
!Personal-Monikers::SyncEngineCOMServer -- ISyncEngineCOMServer
!Personal-Monikers::SyncEngineStorageProviderHandlerProxy--
!Peronal-Monikers::ToastActivation--
!{hexadecimal}--_Application
I suppose I was expecting COM object output like methods and properties... again perhaps I'm reading this all wrong, or this is the right information that is pointing me to something internal and I just don't understand.
I'm seeing a bunch of hexadecimal values and "--INoteLinkContentService"
hexadecimal"--INoteLinkContentService"
!Personal-Monikers::FileSyncClient -- IFileSyncClient9
!Personal-Monikers::SyncEngineCOMServer -- ISyncEngineCOMServer
!Personal-Monikers::SyncEngineStorageProviderHandlerProxy--
!Peronal-Monikers::ToastActivation--
!{hexadecimal}--_Application
I suppose I was expecting COM object output like methods and properties... again perhaps I'm reading this all wrong, or this is the right information that is pointing me to something internal and I just don't understand.
- Attachments
-
- snip_20180220163004.png (13.23 KiB) Viewed 1850 times
- FanaticGuru
- Posts: 1906
- Joined: 30 Sep 2013, 22:25
Re: COM access to non-Microsoft applications
You are getting a list of every active COM object registered with Windows.rynsp8 wrote:Perhaps I'm not familiar enough with COM to understand what the output of the MsgBox is saying:
I'm seeing a bunch of hexadecimal values and "--INoteLinkContentService"
hexadecimal"--INoteLinkContentService"
!Personal-Monikers::FileSyncClient -- IFileSyncClient9
!Personal-Monikers::SyncEngineCOMServer -- ISyncEngineCOMServer
!Personal-Monikers::SyncEngineStorageProviderHandlerProxy--
!Peronal-Monikers::ToastActivation--
!{hexadecimal}--_Application
I suppose I was expecting COM object output like methods and properties... again perhaps I'm reading this all wrong, or this is the right information that is pointing me to something internal and I just don't understand.
If your application is running and not on that list then it has not registered a COM object and probably does not support COM.
An application developer has to code COM support into their application. It is additional work that most application developers do not do. They have to basically code every method and property of their application they want to expose to other programs. It can be alot of work and some programs do not even want to be controllable by other programs.
Microsoft often does it and other high-end applications like Abode and AutoCAD go through the trouble but other smaller applications do not usually want the coding expense. On the other end, some small one coder applications support it because a real geek is doing the coding and it is not just a time to money calculation in development cost.
FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
Re: COM access to non-Microsoft applications
But if there is a COM interface, the best way to learn about the methods/properties is to actually look at its documentation, if you don't want to rely on (often unsatisfying) trial and error or plain guessing.
Apart from that, there are sometimes applications where you can add COM support via plugin/add-ons. The music player Foobar is an example, as far as I remember, although the COM support was rather incomplete and wasn't actively developed anymore for some time (but still working last time I tried).
Apart from that, there are sometimes applications where you can add COM support via plugin/add-ons. The music player Foobar is an example, as far as I remember, although the COM support was rather incomplete and wasn't actively developed anymore for some time (but still working last time I tried).
- FanaticGuru
- Posts: 1906
- Joined: 30 Sep 2013, 22:25
Re: COM access to non-Microsoft applications
That touches on another reason some developers choose not to code COM support, it requires writing a bunch of documentation to go along with the COM support for it to be of much use to others.gregster wrote:But if there is a COM interface, the best way to learn about the methods/properties is to actually look at its documentation, if you don't want to rely on (often unsatisfying) trial and error or plain guessing.
Only thing worse than having to write extensive comments in code is writing extensive documentation outside the code... Well other than not doing either and then having to unravel confusing code. But to be honest I actually hate the act of commenting more than unraveling if I had all the time in the world. So I hate commenting / documenting but I have to because I don't have the time not to.
FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
Re: COM access to non-Microsoft applications
Doing a search for "ISyncEngineCOMServer api"
This web page shows what documentation looks like:
http://docs.rhomobile.com/en/2.2.0/rhod ... ngine-api/
This web page shows what documentation looks like:
http://docs.rhomobile.com/en/2.2.0/rhod ... ngine-api/
Who is online
Users browsing this forum: Google [Bot], prototype_zero and 241 guests