我目前正在尝试使用免注册 COM 运行一个相当复杂的方案。
并不是说它不起作用,而是我遇到了一种令人困惑的情况,似乎我应该直接在应用程序上下文中激活程序集依赖项的清单,而不是让应用程序上下文指向依赖程序集。
由MS 自己发布的示例项目很容易解释:
通常,您有一个应用程序、一个应用程序清单、一个(服务器)dll 及其程序集清单。这些对应于示例给出的内容:
- 客户端程序
- client.exe.manifest(这个指向SideBySide.X as
dependentAssembly
) - SideBySide.dll
- SideBySide.X.manifest
现在,一种标准情况是将客户端应用程序清单嵌入客户端可执行文件中,然后使用 DLL 及其外部清单文件。
现在,如果由于某种原因在编译时不知道正确的应用程序清单,您可以在运行时通过Activation Context API加载清单文件。
这就是令人困惑的地方:
根据文章,客户端应用程序现在直接将其激活上下文切换到程序集清单:
如果您查看 client.cpp 中的 _tmain 函数 ... 一段新的代码,用于初始化激活上下文,如下所示:
actCtx.lpSource = "SideBySide.X.manifest";
我已经对此进行了交叉检查,它也可以动态加载包含来自的信息的文件client.exe.manifest
,即仅对 SideBySide.X 的引用,并继续使用此激活上下文 - 这也对应于我们嵌入时使用的 ActCtx将正确的应用程序清单放入可执行文件中。
也就是说,actCtx.lpSource = "client.exe.manifest";
也可以。
TL;DR直接激活“包含”应用程序代码内的程序集清单的激活上下文(如果有的话)意味着什么。
从文件加载清单时应该这样做吗?(如果是这样,为什么我们不能直接将程序集清单嵌入到可执行文件中,因为它在编译时是已知的。)
注意:(这确实应该是对@Eric Brown 答案的评论,但它变得相当冗长)
链接的文章很好地解释了这两种RT_MANIFEST
资源类型,但关于 regFreeCOM,它留下了一些松散的结尾。我会引用一些让我大吃一惊的引语:
ISOLATIONAWARE_MANIFEST_RESOURCE_ID 主要用于 DLL。如果 dll 需要私有依赖项而不是进程默认值,则应该使用它。... NT 库加载器检查 dll 是否具有 RT_MANIFEST 类型的资源,ID ISOLATIONAWARE_MANIFEST_RESOURCE_ID。如果是,加载程序使用资源调用 CreateActCtx,并使用生成的激活上下文来探测dll 的静态依赖项。
我理解这意味着唯一的一点RT_MANIFEST/2
是静态DLL 依赖加载器找到用于解决DLL 依赖的正确资源。(不是COM 依赖项,见下文。)
有时,您希望在探测 dll 的静态依赖项之外使用激活上下文。您可以在编译模块时定义宏 ISOLATION_AWARE_ENABLED。
定义 ISOLATION_AWARE_ENABLED 后,Windows 会重新定义某些 API。例如 LoadLibraryExW 被重新定义为 IsolationAwareLoadLibraryExW。
... 并非所有受激活上下文影响的 API 都被包装。例如,...,任何 COM API 都不是。
所以,总结一下:我认为 RT_MANIFEST 机制主要与 regFreeCOM 正交,因为 COM 根本不关心它的激活上下文来自哪里,并且 regFreeCOM wrt 没有内置帮助。隔离意识。