我将首先解释我正在尝试做什么(以及为什么),然后再深入了解细节。
我试图让注册免费 COM 激活在编译 JIT 的语言的上下文中工作。我使用 Reg-Fre COM 是因为我想避免注册我的 COM 组件,并且希望这个应用程序可以在没有管理权限的情况下安装。
JIT 编译器是主要的可执行文件,已签名并包含嵌入式清单。默认情况下,最新版本的 Windows 更喜欢嵌入清单而不是外部清单(在 Windows XP 上正好相反)。由于 JIT 已签名,因此我无法在不破坏签名的情况下提取/修改/更新它的清单。此外,这会在我们的应用程序的维护中引入复杂性(始终确保我们嵌入一个新的清单)。修改我不拥有权利的程序也会产生法律影响。
所以,我的想法是尝试让 WinSxS 激活通过一个 Win32 包装库,我将为其提供一个列出依赖项的清单。作为概念验证,我决定制作一个简单的 VB6 应用程序、一个 C++ Wrapper 库和两个 COM 库(1 个在 .NET 中,1 个在 VB6 中)。包装器包含 3 种方法,一种调用 VB6 COM,一种调用 .NET COM,一种返回简单字符串。只要我的 COM 的所有内容都已注册,它当然可以工作。如果我取消注册它们,为 COM 提供清单并将它们作为依赖项添加到主可执行文件的清单中,它就可以工作。如果我取消注册它们,为 COM 和 C++ Wrapper 提供清单并将 com 添加为 C++ Wrapper 的依赖项,然后将 C++ Wrapper 作为主可执行文件清单中的唯一依赖项添加,它可以工作。
请注意,对于我的所有测试,我运行一个 Powershell 脚本来更改我所有文件的修改日期,确保触发激活上下文缓存(清单)。
从那里,我开始使用 SXSTrace.exe 进行调试并设置 COMPlus_LoadLogDir 变量。我发现如果我的清单是外部的,它永远不会被考虑在内。我还发现,如果我将它嵌入到 .DLL 中,sxstrace 会显示它已找到、已解析并且已找到依赖项、已找到它们的清单,并且我在日志中获得了通常成功的上下文激活行。
INFO: Parsing Manifest File C:\RegFreeComWrapper\bin\vbCom.MANIFEST.
INFO: Manifest Definition Identity is vbCom,type="win32",version="1.0.0.0".
INFO: Parsing Manifest File C:\RegFreeComWrapper\bin\netCom.MANIFEST.
INFO: Manifest Definition Identity is netCom,processorArchitecture="msil",version="1.0.0.0".
INFO: Activation Context generation succeeded.
End Activation Context Generation.
然而,即使日志说,我的 COM 调用仍然没有通过。当调用 .NET COM 调用时,我在 COMPlus_CLRLoadLogDir 配置路径中得到一些输出。
在这种情况下,我没有得到任何输出。
一旦我将仅将我的 C++ Wrapper 列为我的主要可执行文件的依赖项的清单添加到我的主可执行文件中,一切都会重新开始工作。我从 SXSTrace 得到了类似的输出,但现在 COM 调用工作了。如前所述,在所有情况下,C++ Wrapper 的简单字符串方法都有效。这意味着即使我的主可执行文件中没有清单,它仍然可以找到我的 .dll 并调用它。如果我没有完整的清单链,似乎 COM 不起作用:Application.Manifest > Wrapper.Manifest > COMs manifests
所以,这里有两件事...... 1.我正在尝试做的事情甚至可能吗?(仅在属于我的 DLL 的清单中列出了依赖项,而不涉及主可执行文件的清单) 2. 如果可能的话,我可能只是遗漏了一件小事来让一切顺利进行......它是什么?:)
如果有人有兴趣尝试使用 em 的东西,我可以提供我所有的代码/可执行文件作为示例。