1

我们的程序需要使用我们自己制作的 COM 服务器。场景如下:安装程序将在每次安装时将程序文件和 COM 服务器文件复制到同一个文件夹中。

目前我们使用 regsvr32 注册 COM 服务器,但这不是很好 - 如果我们开发另一个不相关的程序,也使用相同的 COM 服务器(可能是另一个版本),我们可能会遇到问题 - 因为 CLSID 没有改变,服务器稍后注册的程序将被两个程序使用,第一个程序可能会发生故障。

所以我们需要无注册的 COM。我们可以使用清单,但我已经使用它们一段时间了,发现它们在夜间构建中使用起来不太方便。我们也可以重写程序,而不是调用CoCreateInstance()它调用LoadLibraryEx(),然后GetProcAddress()定位DllGetClassObject(),然后只检索类工厂并使用它。

我立即看到了一些缺点:

  • 该程序将依赖于确切的 COM 服务器文件名
  • 必须为通常由 Windows 管理的内容编写额外的代码
  • COM 服务器必须在进程内,并且永远不会使用编组

并且这些缺点通常可能是展示塞子,但在我们的特定场景中看起来一点也不差。

LoadLibraryEx()使用/DllGetClassObject()相比还有其他缺点CoCreateInstance()吗?

4

2 回答 2

1

我按照您描述的确切过程来实现我自己的轻量级 COM 版本。您正在谈论替换 COM 的“激活”部分。我认为您列出了 COM 激活模型提供的所有功能:

  1. 进程外/单元线程支持
  2. 通过注册表间接解析 CoClass 库位置,允许更新版本、替代实现等。

一旦您动态加载库、检索类工厂并构造您的对象,它的行为应该与您通过 COM 在您的公寓内创建一个进程内对象没有什么不同。

于 2011-06-04T23:28:48.810 回答
0

1 . 该程序将依赖于确切的 COM 服务器文件名

通过使用DLL 延迟加载通知挂钩和处理dliNotePreLoadLibrary(即抢占加载),您可以从具有与客户端导入表中记录的文件名不同的文件名的 DLL 加载。

事实上,您可以指定您希望在命令行中使用的实际 DLL 文件名,甚至是配置文件。(我最近才这样做。)只要您不尝试在使用该库之前使用该库。

2 . 必须为通常由 Windows 管理的内容编写额外的代码

至于GetProcAddress延迟加载辅助实用程序提供了一次从单个模块加载所有导入的功能。

3 . COM 服务器必须在进程内,并且永远不会使用编组

至于编组 - 我不熟悉这个领域,但这里有一些想法:

  • 需要实现自己的代理/存根代码以自己的方式处理进程间通信

这意味着您需要编写自己的编组编译器,恐怕。你可能会发现其他人已经这样做了。

一旦完成,客户端将LoadLibrary成为代理,代理将启动存根可执行文件(进程外)来托管服务器,存根将LoadLibrary成为实际的服务器。

这基本上是对 COM 的彻底改造。

于 2011-06-05T00:18:27.320 回答