LoadLibrary()无法加载包含清单和专用程序集的DLL
我正在使用多个DLL的Windows应用程序(EXE)上工作。开发是在VCExpress 2005(VC8.0)中进行的,仅使用C 其中一些DLL是插件/加载项/扩展,根据EXE读取的配置文件使用动态加载 重要提示:应用程序必须是可移植的(在某种意义上说,无需安装即可从USB闪存驱动器或类似设备运行),并且插件DLL可能与应用程序EXE不在同一文件夹中(遗留原因) 对于MSVC6,这很简单:编译、链接、分发EXE和DLL 对于MSVC8,C运行时库(MSVCRT)不再随操作系统一起分发,因此不能依赖于它的安装。为了满足可移植性要求,我需要使用。所有的EXE和DLL都嵌入了它们的清单 我的问题:通过LoadLibrary()无法加载包含清单和专用程序集的DLL,dll,manifest,msvcrt,loadlibrary,Dll,Manifest,Msvcrt,Loadlibrary,我正在使用多个DLL的Windows应用程序(EXE)上工作。开发是在VCExpress 2005(VC8.0)中进行的,仅使用C 其中一些DLL是插件/加载项/扩展,根据EXE读取的配置文件使用动态加载 重要提示:应用程序必须是可移植的(在某种意义上说,无需安装即可从USB闪存驱动器或类似设备运行),并且插件DLL可能与应用程序EXE不在同一文件夹中(遗留原因) 对于MSVC6,这很简单:编译、链接、分发EXE和DLL 对于MSVC8,C运行时库(MSVCRT)不再随操作系统一起分发,因此不能
LoadLibrary()
加载的插件DLL找不到EXE文件夹中的私有程序集,因此除非在winSxS中安装了Microsoft.VC80.CRT
程序集,否则加载它们的尝试将失败
陷阱:如果从插件DLL中删除清单,则一切正常
我的问题:
我试图通过将程序集放在DLL旁边并更改当前目录(以排除与工作目录相关的情况)来验证这一点,并获得预期的行为。其他人是否可以确认这是SxS使用
LoadLibrary
时的正常行为msvcr80.DLL
(而不是程序集清单Microsoft.VC80.CRT.manifest
)的非SxS加载顺序,这一假设正确吗与CRT静态链接。只要在应用程序(纯C/C++)中不使用.Net,就有可能静态链接到CRT
Net在我的应用程序中的引入迫使我从静态链接的CRT转向动态链接的CRT。我还试图找到一种在本地引用CRT DLL的方法,而无需显式安装它们,但我没有找到它。因此,如果可能,静态链接到CRT。您需要了解激活上下文是什么,才能理解此问题 带有清单的exe或dll具有激活上下文-激活上下文是在分析清单时发现的窗口类、依赖程序集、dll和无注册com引用的列表 没有清单的exe或dll使用进程默认激活上下文-如果exe具有激活上下文,则通常是exe的激活上下文 在您的例子中,dll有自己的激活上下文——因为它有一个清单。并且它始终是搜索程序集的清单文件(包含该清单文件的文件/文件夹)的路径 这就是为什么windows首先搜索dll文件夹中的专用程序集。然后,当该操作失败时,Windows将在标准加载库搜索路径中搜索dll:该dll以exe的根文件夹开始。但它现在搜索的是dll,而不是程序集,因此找不到包含dll的程序集文件夹
谢谢-我看到了这一点,并讨论了静态链接与动态链接的相对优点。我对使用静态链接犹豫不决,因为我不确定API是否允许/期望在不同的模块中发生资源分配和释放,这将导致应用程序崩溃。静态链接也会导致二进制文件膨胀。需要添加一点-当嵌入清单包含publicKeyToken引用时,加载程序似乎会忽略应用程序本地目录。如果有足够的信息,加载程序总是首先在WinSxS中查找。但是,即使有publicKeyToken,它也会返回到本地。