Mar*_* Ba 4 winapi side-by-side regfreecom visual-c++ activation-context-api
我目前正在尝试使用免注册 COM 来运行一个相当复杂的方案。
并不是说它不起作用,而是我遇到了一种令人困惑的情况,似乎我应该直接在应用程序上下文中激活程序集依赖项的清单,而不是让应用程序上下文指向依赖程序集。
通过MS 自己发布的示例项目很容易解释:
通常,您有一个应用程序、一个应用程序清单、一个(服务器)dll 及其程序集清单。这些对应于示例给出的内容:
dependentAssembly)现在,一种标准情况是将客户端应用程序清单嵌入到客户端可执行文件中,然后使用 DLL 及其外部清单文件。
现在,如果出于某种原因在编译时无法知道正确的应用程序清单,您可以在运行时通过Activation Context API加载清单文件。
这就是令人困惑的地方:
根据该文章,客户端应用程序现在直接将其激活上下文切换到程序集清单:
如果您查看 client.cpp 中的 _tmain 函数...初始化激活上下文的新代码部分如下:
Run Code Online (Sandbox Code Playgroud)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 的静态依赖项。
我的理解是,静态DLL 依赖项加载器的唯一目的是找到正确的资源来解决DLL 依赖项。(不是COM 依赖项,请参见下文。)RT_MANIFEST/2
有时,您希望在探测 dll 的静态依赖项之外使用激活上下文。您可以在编译模块时定义宏 ISOLATION_AWARE_ENABLED。
定义 ISOLATION_AWARE_ENABLED 后,Windows 会重新定义某些 API。例如,LoadLibraryExW 被重新定义为 IsolationAwareLoadLibraryExW。
...并非所有受激活上下文影响的 API 都被包装。例如,...,任何 COM API 都不是。
所以,总结一下:我认为 RT_MANIFEST 机制主要与 regFreeCOM 正交,因为 COM 根本不关心它的激活上下文来自哪里,并且没有针对 regFreeCOM 的内置帮助。隔离意识。
是的,这就是应该如何完成的,您可以将程序集清单嵌入到可执行文件中(好吧,资源部分)。这就是RT_MANIFEST资源类型的用途。清单资源有两种默认类型
ID CREATEPROCESS_MANIFEST_RESOURCE_ID(1),在流程创建期间使用,ID ISOLATIONAWARE_MANIFEST_RESOURCE_ID(2)在 DLL 加载期间使用。 有几个用途(主要围绕单击一次部署)说明了使用 RT_MANIFEST 在附属 DLL 中嵌入免注册 COM 清单的能力。特别是,如果 DLL 具有 CREATEPROCESS_MANIFEST_RESOURCE_ID,则也将使用该清单。
这里有一个例子似乎是一件好事。
给定
如果 sidebyside.dll 具有 ID 为 1 (CREATEPROCESS_MANIFEST_RESOURCE_ID) 的 RT_MANIFEST 资源,其中包含适当的免注册 COM 条目,并且 client.exe 具有 ID 为 1 的 RT_MANIFEST 资源,其中包含<file>sidebyside.dll 的条目,则 Win32 将自动处理免注册COM管理。
示例文章的第 8 部分强烈暗示了这一点,并且我已经在许多内部项目中看到了这一点。