【问题标题】:How to separate managed and unmanaged DLLs in another directory如何在另一个目录中分离托管和非托管 DLL
【发布时间】:2012-04-20 03:10:14
【问题描述】:

我的发布文件夹是:

MyApp.exe
MyManagedDLL.dll
NativeDLL.dll

MyApp 使用通过 pinvoke 本机 dll 调用的托管 dll。 我试图将它们移动到另一个子文件夹文件夹并再次引用托管 dll,当我运行我的应用程序时它说它找不到 NativeDLL.dll。如何解决?

【问题讨论】:

  • 项目是在运行时显式引用dll还是加载?
  • 它不会在运行时加载它们。它仅引用托管 dll。
  • 托管 dll 如何了解 nativedll?

标签: .net dll unmanaged .net-assembly


【解决方案1】:

Windows 不知道它需要在子目录中查找 DLL。它只会在选定的几个位置查找 DLL,从包含 EXE 的文件夹开始。给它一个艰难的时期,它不是很有成效。但是您可以通过调用 SetDllDirectory() 来帮助它。请记住,您的用户不会关心 DLL 的位置。 IT 部门倾向于使用简单的解决方案,当应用程序本身正在改变 Windows 搜索路径时,解决 DLL 加载问题从来都不是一件有趣的事情。

否则,允许 AnyCPU 可执行文件在 32 位和 64 位模式下运行是一种合理的方法。您将使用 两个 目录,一个使用 32 位版本的 DLL,另一个使用 64 位版本。并根据 IntPtr.Size 的值相应地调用 SetDllDirectory。

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern bool SetDllDirectory(string lpPathName);

【讨论】:

  • 谢谢,但我不想更改用户的 PATH。
  • 嗯,这通常是非常邪恶的,但实际上在托管代码中并没有那么大的问题。因为你可以自己调用 Environment.SetEnvironmentVariable() before 你调用任何 pinvoked 方法。与调用 SetDllDirectory() 没有太大区别。
  • 是的,我知道。也许你知道一些工具,我可以使用它从编译的程序集中将 DLLImport 字符串更改为“myDir\some.dll”?
  • 这不可能,属性构造函数数据存储在程序集元数据中。这样做也不是明智之举,当应用程序的默认工作目录未设置在您希望设置的位置时,这将随机失败。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-31
  • 1970-01-01
  • 2011-03-02
  • 1970-01-01
  • 2010-10-14
相关资源
最近更新 更多