Assembly.LoadFrom如何解决非托管依赖项?

 伊子夕2010_593 发布于 2023-02-09 09:52

我对这种行为感到困惑Assembly.LoadFrom.在我的应用程序中,我调用Assembly.LoadFrom.NET .exe并使用它来启动它EntryPoint.Invoke(这种奇怪的方法对于在非Windows平台上构建启动器应用程序非常有用).

我曾假设,因为它assemblyFile位于不同的文件夹中,所以它无法找到与它位于同一文件夹中的某些托管 .dll依赖项.但它奏效了; 它并没有失败......

这样看来,当我打电话Assembly.LoadFrom(assemblyFile),它包含检查的文件夹assemblyFile进行管理的依赖关系assemblyFile.我没想到这一点.如果该程序集具有非托管依赖项(例如a DllImport)会发生什么情况,它仍会搜索同一目录吗?这个行为框架是否具体?

1 个回答
  • Assembly与加载非标记库无关.非托管库的加载是DllImport什么是懒惰的调用(直到第一次调用才加载).

    DllImport反过来(在.NET中,我不知道Mono在其他平台上做了什么)LoadLibary在Windows 上调用.LoadLibary有一组已知的规则来解决它的依赖关系:

    如果已在内存中加载具有相同模块名称的DLL,则系统将使用加载的DLL,无论它在哪个目录中.系统不会搜索DLL.

    如果DLL位于运行应用程序的Windows版本的已知DLL列表中,则系统将使用其已知DLL(以及已知DLL的相关DLL,如果有)的副本.系统不搜索DLL.有关当前系统上已知DLL的列表,请参阅以下注册表项:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs.

    如果未满足这两点并且SafeDllSearchMode已启用(默认情况下为XP SP2及更高版本),则使用以下顺序

      加载应用程序的目录.

      系统目录.使用GetSystemDirectory函数获取此目录的路径.

      16位系统目录.没有函数可以获取此目录的路径,但会搜索它.

      Windows目录.使用GetWindowsDirectory函数获取此目录的路径.

      当前目录.

      PATH环境变量中列出的目录.请注意,这不包括App Paths注册表项指定的每个应用程序路径.计算DLL搜索路径时不使用App Paths键.


    因此,要回答您的问题,在查找非托管程序集时,不会搜索托管程序集所在的目录,也不会搜索加载托管程序集的应用程序的目录.

    但是,所有希望都不会丢失,您可以调用SetDLLDirectory并添加托管程序集的文件夹,并在查找非托管DLL时将其包含在搜索中,它会将搜索顺序更改为

      加载应用程序的目录.

      lpPathName参数指定的目录(在SetDLLDirectory调用中).

      系统目录.使用GetSystemDirectory函数获取此目录的路径.该目录的名称是System32.

      16位系统目录.没有函数可以获取此目录的路径,但会搜索它.该目录的名称是System.

      Windows目录.使用GetWindowsDirectory函数获取此目录的路径.

      PATH环境变量中列出的目录.

    如果您需要添加多个文件夹进行搜索,请参阅MSDN以获取有关AddDllDirectory允许多个搜索目录所需步骤的文档.

    2023-02-09 09:58 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有