是否可以将免注册 COM 应用于 DLL



目前,我有这样的东西用于免注册的COM设置:

  • a.exe(取决于b.dll;不直接取决于c.dll
  • a.exe.manifest(声明c.dll免注册 COM 注册)
  • b.dll(取决于c.dll。例如,.NET TMBIMP 生成的 COM 包装器)
  • c.dll(某些 COM 实现 DLL)
  • c.dll.manifestc.dll的免注册 COM 清单)

是否可以更改此方案,以便将a.exe上的清单放在b.dll上?我希望其他程序能够引用b.dll,而不必在可能的情况下在任何地方添加其他清单。

a.exe.manifest有这样的内容:

  <file name="msdia110.dll">
    <comClass description="Debug Information Accessor" clsid="{761D3BCD-1304-41D5-94E8-EAC54E4AC172}" threadingModel = "Both"/>
  </file>

并且c.dll.manifest是使用清单工具生成的 mt.exe 。(而且太长了,无法在此处列出)

我的经验是它不起作用,或者更确切地说,您需要调用激活上下文 API 才能在 DLL 中实际使用清单: 请参阅此问题: 将清单文件移动到 dll?

我对此的看法,虽然可能不完全准确,是这样的:

  • 基于注册表的 COM 是每个用户的"全局"

  • Regfree 清单 COM 是每个进程的"全局",应在可执行文件上进行管理

只有可执行清单始终"在范围内",如果你的 DLL 有一个 COM 并行清单,则强制使用激活上下文 API 显式加载它,问题是它只有在你确切知道何时需要它并控制调用路径到DLL中需要它的位置时才能工作。

因为,据我了解,当您拥有"a.exe.manifest(声明 c.dll 的免注册 COM 注册)"时,您真正要做的是修改该过程的初始/全局激活上下文。这(似乎)仅适用于可执行清单。加载 DLL 后,DLL 的任何清单都不会自动使用,因此当您需要无注册 COM 清单时,即在CoCreateInstance之前,您必须手动执行此操作。

我有一个案例,我认为我知道何时调用CoCreateInstance并且我需要开关,但后来发现 DLL 生成了一些线程,这些线程自己执行了一些 CoCreateInstance。(我无法控制激活上下文的地方。

所以总结一下,我会说:

  • 如果可以,请在可执行文件中包含 SxS COM 清单
  • 如果您完全了解并且可以控制何时切换上下文("手动"),则可以使用激活上下文 API,但与仅在可执行文件中嵌入清单相比,这似乎要麻烦得多。

最新更新