LoadLibrary()无法加载带有清单和私有程序集的DLL

时间:2010-02-25 16:06:36

标签: dll manifest msvcrt loadlibrary

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

这些DLL中的一些是根据EXE读取的配置文件使用LoadLibrary动态加载的插件/加载项/扩展。

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

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

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

我的问题:通过LoadLibrary()加载的插件DLL找不到EXE文件夹中的私有程序集,因此尝试加载它们会失败,除非{{1} } assembly安装在winSxS中。

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

我的问题

  1. 在问题的情况下,Windows似乎没有关注Assembly searching sequenceDynamic link library search order。具体来说,它是在加载DLL的路径中查找私有程序集,而不是从中加载应用程序(EXE)。 我试图通过将程序集放在DLL附近,并更改当前目录(以排除与工作目录案例相关)来验证这一点,并获得预期的行为。在将Microsoft.VC80.CRT与SxS一起使用时,是否有其他人可以确认这是正常行为?

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

  3. 如果我对(1)和(2)是对的,那么只要从DLL中排除清单我会失去什么?重新说明,为什么我不应该通过排除清单来解决我的问题?

2 个答案:

答案 0 :(得分:10)

您需要了解激活上下文是什么来理解这个问题。

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

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

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

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

  1. 没有。如果没有清单,则dll会回退到使用默认激活上下文:exe的清单。 This Blog Article解释了一下。

  2. 排除清单。你放松的是能够让dll指定自己的依赖程序集。因此,您需要将dll所需的任何依赖程序集添加到应用程序清单中。

答案 1 :(得分:0)

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

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