gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 19:01:52 27 4
gpt4 key购买 nike

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

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

看起来,当我调用 Assembly.LoadFrom(assemblyFile) 时,它会检查包含 assemblyFile 的文件夹中是否有 managed 依赖项>程序集文件。我没想到会这样。如果该程序集具有非托管 依赖项(例如 DllImport),会发生什么情况,它是否仍会搜索同一目录?这个行为框架是特定的吗?

最佳答案

程序集 与加载非托管库无关。加载非托管库的是 DllImport 调用,它是惰性的(直到第一次调用才加载)。

DllImport 依次(在 .NET 中,我不知道 Mono 在其他平台上做了什么)调用 LoadLibary在 window 上。 LoadLibarya known set of rules关于它如何解决它的依赖关系:

  • 如果内存中已经加载了具有相同模块名称的 DLL,系统将使用加载的 DLL,无论它位于哪个目录。系统不会搜索 DLL。
  • 如果 DLL 在运行应用程序的 Windows 版本的已知 DLL 列表中,系统将使用已知 DLL 的副本(以及已知 DLL 的依赖 DLL,如果有的话)。系统不搜索 DLL。有关当前系统上已知 DLL 的列表,请参阅以下注册表项:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs

如果没有满足这两点并且启用了SafeDllSearchMode(对于 XP SP2 和更新版本,它是默认设置)它使用以下顺序

  1. 应用程序加载的目录。
  2. 系统目录。使用 GetSystemDirectory 函数获取此目录的路径。
  3. 16 位系统目录。没有获取该目录路径的函数,但是搜索到了。
  4. Windows 目录。使用 GetWindowsDirectory 函数获取此目录的路径。
  5. 当前目录。
  6. PATH 环境变量中列出的目录。请注意,这不包括应用程序路径注册表项指定的每个应用程序路径。计算 DLL 搜索路径时不使用 App Paths 键。

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

不过希望还未落空,您可以调用SetDLLDirectory并添加托管程序集的文件夹,它会在查找非托管 DLL 时将其包含在搜索中,它将搜索顺序更改为

  1. 应用程序加载的目录。
  2. lpPathName 参数指定的目录(在 SetDLLDirectory 调用中)。
  3. 系统目录。使用 GetSystemDirectory 函数获取此目录的路径。此目录的名称是 System32。
  4. 16 位系统目录。没有获取这个目录路径的函数,但是搜索到了。此目录的名称是系统。
  5. Windows 目录。使用 GetWindowsDirectory 函数获取此目录的路径。
  6. PATH 环境变量中列出的目录。

如果您需要添加多个文件夹进行搜索,请参阅 MSDN 上的文档 AddDllDirectory了解允许多个搜索目录所需的步骤。

关于c# - Assembly.LoadFrom 如何解决非托管依赖项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20691397/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com