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

Twy*_*ite 8 dll manifest msvcrt loadlibrary

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

其中一些DLL是插件/加载项/扩展,它们LoadLibrary根据EXE读取的配置文件动态加载.

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

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

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

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

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

我的问题:

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

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

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

Chr*_*cke 10

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

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

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

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

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

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

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


Pat*_*ick 0

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

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