8

我正在开发一个使用多个 DLL 的 Windows 应用程序 (EXE)。开发在 VCExpress 2005 (VC 8.0) 中,仅使用 C。

LoadLibrary其中一些 DLL 是根据 EXE 读取的配置文件 动态加载的插件/附加组件/扩展。

重要的是:应用程序必须是可移植的(即无需安装即可从 USB 闪存驱动器或类似设备运行),并且插件 DLL 可能与应用程序 EXE 不在同一文件夹中(遗留原因)。

使用 MSVC6,这很简单:编译、链接、分发 EXE 和 DLL。

使用 MSVC8,C 运行时库 (MSVCRT) 不再随操作系统分发,因此不能依赖它的安装。为了满足可移植性要求,我需要使用私有程序集。所有的 EXE 和 DLL 都嵌入了它们的清单。

我的问题:通过加载的插件 DLLLoadLibrary()找不到 EXE 文件夹中的私有程序集,因此除非Microsoft.VC80.CRT程序集安装在 winSxS 中,否则尝试加载它们会失败。

问题:如果清单从插件 DLL 中删除,一切正常。

我的问题

  1. 在问题案例中,Windows 似乎没有遵循Assembly 搜索顺序动态链接库搜索顺序。具体来说,它在加载 DLL 的路径中查找私有程序集,而不是从加载应用程序 (EXE) 的路径中。
    我试图通过将程序集与 DLL 相邻并更改当前目录(以排除与工作目录相关的情况)来验证这一点,并获得预期的行为。其他人可以确认这是LoadLibrary与 SxS 一起使用时的正常行为吗?

  2. 我是否正确假设没有清单,DLL 会退回到在 EXE 的文件夹中找到msvcr80.dll(而不是程序集清单)的非 SxS 加载顺序?Microsoft.VC80.CRT.manifest

  3. 如果我对 (1) 和 (2) 的看法是正确的,那么仅从 DLL 中排除清单会失去什么?换个说法,为什么我不应该通过排除清单来解决我的问题?

4

2 回答 2

10

您需要了解什么是激活上下文才能理解此问题。

带有清单的 exe 或 dll 具有激活上下文 - 激活上下文是在解析清单时发现的窗口类、依赖程序集、dll 和无注册 com 引用的列表。

没有清单的 exe 或 dll 使用进程默认激活上下文 - 如果 exe 具有激活上下文,则通常是 exe 的激活上下文。

在您的情况下,dll 有自己的激活上下文 - 因为它有一个清单。它始终是搜索程序集的(包含该文件/文件夹)清单文件的路径。

这就是为什么windows首先在dll的文件夹中搜索私有程序集的原因。然后,当失败时,Windows 会在标准加载库搜索路径中搜索 dll:从 exe 的根文件夹开始。但是它现在搜索 dll,而不是程序集 - 所以找不到包含 dll 的程序集文件夹。

  1. 没有。没有清单,dll 会退回到使用默认激活上下文:exe 的清单。这篇博客文章对此做了一些解释。

  2. 排除清单。您失去的是让 dll 指定其自己的依赖程序集的能力。因此,您需要做的是将 dll 需要的任何依赖程序集添加到应用程序清单中。

于 2010-03-10T15:12:57.547 回答
0

与 CRT 静态链接。只要您不在应用程序中使用 .Net(纯 C/C++),它就可能与 CRT 进行静态链接。

在我的应用程序中引入 .Net 迫使我从静态链接的 CRT 转移到动态链接的 CRT。我还试图找到一种无需显式安装即可在本地引用 CRT DLL 的方法,但我没有找到。因此,如果可能,静态链接与 CRT。

于 2010-02-25T17:24:10.020 回答