可以将免注册 COM 应用于 DLL 吗?

Posted

技术标签:

【中文标题】可以将免注册 COM 应用于 DLL 吗?【英文标题】:Can registration free COM be applied to a DLL? 【发布时间】:2014-05-13 00:21:31 【问题描述】:

目前我有类似这样的免注册 COM 设置:

a.exe(依赖于b.dll;不直接依赖于c.dlla.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 来控制哪些清单在加载点处于活动状态。 从技术上讲,是的。并非没有麻烦,b.dll 是一个自动生成的文件,因此您必须控制它并使用 mt.exe 进行猴子嵌入清单。使用 ID 2。.NET 4 Embed Interop Types 功能也很麻烦,非常需要,但它会使 b.dll 消失。 @Hans:在这种情况下,b.dll 不会自动生成。 (tlbimp 在这里出错了很多,我们不得不反编译,弄乱 IL,然后重新编译) @BillyONeal,是的,这是可能的。您甚至可以拥有仅包含依赖项的清单,以及引用多个 DLL 的清单。 Move manifest file to dll? 的可能重复项 【参考方案1】:

我的经验是它不起作用,或者您需要调用 Activation Context API 才能实际使用 DLL 中的清单:请参阅此问题:Move manifest file to dll?

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

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

Regfree manifest COM 对每个进程都是“全局的”,应该在可执行文件上进行管理

只有可执行清单总是“在范围内”,如果你的 DLL 有一个 COM 并行清单,你必须使用 Activation Context API 显式加载它,问题在于它只有当您确切地知道何时需要它并控制调用路径到 DLL 中需要它的位置时才能工作。

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

I had a case 我以为我知道何时调用 CoCreateInstance 并且我需要开关,但后来发现 DLL 产生了一些线程,它们自己执行了一些 CoCreateInstance。 (我无法控制的激活上下文。)

总结起来就是:

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

【讨论】:

所以,您的回答是,“是的,如果 .EXE 事先知道的话”,这违背了将其放在 DLL 中的目的。 @BillyONEal:我说技术上在某些情况下,EXE 不需要知道任何东西,但据我所知,在练习唯一能正常工作的是将清单放在EXE中。 (但我们已经在问题的 cmets 中讨论过这个问题,不是吗?) @BillyONEal:但是你看,我在整个问题上都非常称我为专家,所以我真的很想自己找到一个明确的答案。因此,如果我们在一些基本问题上存在分歧(从我们的评论讨论中看来),我很乐意再谈一谈。

以上是关于可以将免注册 COM 应用于 DLL 吗?的主要内容,如果未能解决你的问题,请参考以下文章

免注册 COM/DLL?

如何找到哪个未注册的 DLL 正在实现 COM 对象?

通过注册的 TLB 从 python 访问未注册的 COM 对象

如何使用 Regsvr32 注册 .NET COM DLL?

注册 DLL 有啥作用?

使用 DLL 中的 COM 对象,无需注册