通过COM连接运行中程序:如何获取Marshal.GetIUnknownForObject所需unknown对象
如何从外部连接基于COM接口的应用程序进行自动化操作?
我正在使用一款提供扩展包的软件,该扩展包文档极不完整,可创建用于程序内自动化的扩展,其基于插件/扩展与运行中软件间的COM接口。我需要在软件运行时从外部连接并执行自动化操作。
有限的示例代码展示了从软件内执行插件时会被调用的方法:
AppComExtensionWrapper m_wrapper; const int S_FALSE = 1; public int AppConnect(object unknown) { try { IntPtr p = Marshal.GetIUnknownForObject(unknown); return m_wrapper.AppComConnect(p); } catch { return S_FALSE; } }
当从应用内调用扩展时,会调用AppConnect方法并传入unknown对象。
问题: 在外部运行时,我该如何获取unknown对象并连接到应用?或者是否有其他连接应用的方法?我已尝试通过System.Diagnostics获取运行进程,但不确定如何以此建立连接,目前陷入困境。
可行的解决方案
查找应用公开的COM ProgID/CLSID
多数支持COM自动化的应用会注册全局COM对象,你可以通过以下方式尝试获取实例:// 替换为目标软件的ProgID Type appType = Type.GetTypeFromProgID("TargetApp.Automation"); if (appType != null) { object appInstance = Activator.CreateInstance(appType); // 尝试将该实例传入AppConnect逻辑,或直接调用其公开的自动化方法 IntPtr ptr = Marshal.GetIUnknownForObject(appInstance); m_wrapper.AppComConnect(ptr); }可以通过注册表
HKEY_CLASSES_ROOT项查找软件的ProgID,或使用OLE/COM Object Viewer工具查看已注册的COM对象列表。通过进程注入获取COM接口
若软件未公开全局COM对象,可通过进程注入在目标进程内获取unknown对象,再通过跨进程通信传递到外部程序:- 编写轻量DLL,注入目标进程后模拟内部插件逻辑,获取
unknown对象的IUnknown指针。 - 使用
Marshal.GetIUnknownForObject获取指针值,通过命名管道、共享内存等方式传递给外部程序。 - 外部程序接收指针后,用
Marshal.GetObjectForIUnknown转换为对象,再调用AppComExtensionWrapper.AppComConnect。
注意:进程注入需处理系统权限限制,且目标COM接口需支持跨进程列集(实现IMarshal或使用系统默认列集器)。
- 编写轻量DLL,注入目标进程后模拟内部插件逻辑,获取
尝试使用GetActiveObject获取运行中实例
如果应用已注册到运行对象表(ROT),可直接获取正在运行的实例:try { // 替换为目标软件的ProgID object appInstance = Marshal.GetActiveObject("TargetApp.Automation"); IntPtr ptr = Marshal.GetIUnknownForObject(appInstance); m_wrapper.AppComConnect(ptr); } catch (COMException ex) { // 处理实例未运行的情况 }
内容的提问来源于stack exchange,提问作者GisMofx
相关产品推荐
相关产品推荐

