免注册的COM能应用于DLL吗?

6

目前,我正在进行无需注册的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 来控制在加载时哪些清单是活动的。 - David Heffernan
从技术上讲,是可以的。但是这需要付出很大的努力,因为b.dll是一个自动生成的文件,所以你必须控制它并使用mt.exe来嵌入清单。请使用ID 2。.NET 4 Embed Interop Types功能也非常麻烦,虽然非常理想,但会使b.dll消失。 - Hans Passant
@Hans:在这种情况下,b.dll没有自动生成。(tlbimp在这里出了很多问题,我们不得不反编译、处理IL代码并重新编译) - Billy ONeal
可能是将清单文件移动到dll中?的重复问题。 - Martin Ba
@Martin:那个问题讨论的是LoadLibrary,而不是Registration-Free COM。 - Billy ONeal
显示剩余4条评论
1个回答

0

我的经验是它不起作用,或者说你需要调用激活上下文 API 来实际使用 DLL 中的清单:请参见这个问题:将清单文件移动到 dll?

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

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

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

只有可执行文件清单始终处于“范围”内,如果您的 DLL 具有 COM 并排清单,则必须使用激活上下文 API 显式加载此清单,而其中的问题是仅当您知道确切地何时需要它并控制调用路径到 DLL 中需要它的位置时才能工作。

因为,根据我的理解,当你有一个 "a.exe.manifest(声明 c.dll 的无注册 COM 注册)" 时,你实际上要做的是修改该进程的初始/全局激活上下文。这只对可执行文件清单有效。任何 DLL 的清单在加载 DLL 后不会自动使用,所以在您需要 reg-free COM 清单的地方手动操作,即在 CoCreateInstance 之前进行。

我曾经遇到过一种情况,我认为我知道何时调用 CoCreateInstance 并需要该开关,但后来发现 DLL 生成了一些线程,并进行了一些 CoCreateInstance 操作(其中我不能控制激活上下文)。

因此,总结起来,我想说:

  • 如果可以的话,在可执行文件中包含 SxS COM 清单
  • 如果您完全知道并可以控制何时切换上下文(“手动”),则可以使用激活上下文 API,但与在可执行文件中嵌入清单相比,这似乎更麻烦。

所以,你的答案是,“是的,如果.EXE事先知道”,这就打破了一开始将其放在DLL上的目的。 - Billy ONeal
@BillyONeal:我说“从技术上讲”,有些情况下EXE不需要知道任何东西, - Martin Ba
@BillyONeal:但你看,我离称自己是这个问题的专家还有很长的路要走,所以我真的很想找到一个明确的答案。所以如果我们在一些基本问题上存在分歧(从我们的评论讨论中看来是这样),我很乐意再谈谈。 - Martin Ba

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接