3

我目前正在尝试使用免注册 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 没有内置帮助。隔离意识。

4

1 回答 1

4

是的,这就是它应该完成的方式,您可以将程序集清单嵌入到可执行文件中(嗯,资源部分)。这就是RT_MANIFEST资源类型的用途。清单资源有两种默认类型

  • 流程清单,带有ID CREATEPROCESS_MANIFEST_RESOURCE_ID(1),在流程创建期间使用,
  • ID ISOLATIONAWARE_MANIFEST_RESOURCE_ID在 DLL 加载期间使用 具有 (2) 的隔离感知清单。

有几个用途(主要围绕 Click-once 部署)说明了使用 RT_MANIFEST 在附属 DLL 中嵌入免注册 COM 清单的能力。特别是,如果 DLL 具有 CREATEPROCESS_MANIFEST_RESOURCE_ID,则也将使用该清单。

一个例子在这里似乎是一件好事。

给定

  • 客户端程序
  • sidebyside.dll

如果 sidebyside.dll 有一个 ID 为 1 (CREATEPROCESS_MANIFEST_RESOURCE_ID) 的 RT_MANIFEST 资源,其中有适当的免注册 COM 条目,并且 client.exe 有一个 ID 为 1 的 RT_MANIFEST 资源,它有一个<file>sidebyside.dll 的条目,那么 Win32 将自动处理免注册COM管理。

示例文章的第 8 部分强烈暗示了这一点,我已经在许多内部项目中看到了这一点。

于 2013-10-15T16:37:56.660 回答