0

要么我不理解 COM 对象,要么这一切都令人困惑。我经常“创建”、“调度”COM 对象——无论是在 Python 中,还是在 VB 中(Obj = win32com.client.Dispatch('Visum.Visum')Obj = CreateObject("Excel.Application")分别)。这很容易,很明显,一切都很好。但是我怎么能:a)连接到已经运行的 COM 对象 b)获取作为 COM 对象的正在运行的进程列表

高度混乱(COM 对象、服务器?连接、调度、注册??)

感谢您澄清 Rafal i2

4

2 回答 2

2

首先,我建议阅读一个很好的 COM 介绍。就个人而言,我认为 Don Box 的“Essential COM”是关于 COM 的最佳书籍。花几个小时使用它会为您节省很多小时。

话虽如此,让我们转向您的问题。

a) 为了从 VB 中检索现有的 COM 对象,您需要调用GetObject函数。这仅适用于使用Running Object Table注册的 COM 对象。Excel会这样做,所以应该没有任何问题。

b) 正如 Hans Passant 正确指出的那样,这个问题没有意义。进程和 COM 对象是完全不相关的东西,除了进程承载 COM 对象这一事实。这类似于询问“哪些进程是 X 类的实例”。但是,一个进程可以承载一个 COM 对象(或其中许多)。这些对象只能暂时活着,所以你会期待什么?此外,许多 COM 类是在 dll 中实现的,但创建的实例显然是托管在一个进程中的——那么你会期待什么呢?

于 2012-12-11T09:51:42.897 回答
0

COM 技术是我有一段时间没有使用的东西,如果某些信息可能有误,非常抱歉(无论如何,我有我的书“内部 COM+ 基础服务”!)

简而言之,让我们给出一个 COM 对象的简化定义:它只不过是一个标准 DLL,其类通过以下方法公开一个标准接口 IUnkown:

  • AddRef:注册一个使用 COM 对象的客户端
  • 释放:取消注册客户端(通常未使用的对象停止运行,但其他可能保持常驻)
  • QueryInterface:获取函数的地址

QueryInterface 用于动态检索函数的地址(后期绑定),它功能强大(您不必在编译时知道 DLL)但耗时。另一方面,您可以在编译时直接引用函数的地址,因为这些DLL是在系统中注册的(所有信息都存储在注册表中)

创建新对象或获取正在运行的对象的地址是通过 RPC(远程过程调用)完成的,它将加载和/或扮演代理的角色

因此,要创建 COM 对象的新实例,您将在 VC++(甚至 c#?)中调用 CreateObject(在 VB 中)(Co)CreateInstance,而要获取正在执行的实例,您可能需要调用 GetObject()。

获取 COM 对象列表并不容易(我想根本不可能),因为如前所述,COM 对象只不过是一个 DLL:这意味着该库将主要加载到每个进程的地址空间中访问是私人的。即使对于在许多进程之间共享对象的进程外 COM 对象(与进程内相反)(即:Excel 是进程外 COM 对象:您不会在应用程序的地址空间中加载 DLL),它们由主机(rpc.exe 或专有主机)加载

希望这有助于塞尔

于 2012-12-10T23:37:13.100 回答