【问题标题】:Catch DllNotFoundException from P/Invoke从 P/Invoke 捕获 DllNotFoundException
【发布时间】:2010-12-13 18:57:19
【问题描述】:

找到解决方案的帖子How do I handle a failed DllImport?

我正在编写一个应用程序来检查操作系统版本以根据主机使用的是 Vista 系列还是 NT 系列版本的 Windows 来执行不同的操作。如果是 Vista 系列,它会加载一些 DLL(使用 DllImport),但不使用这些。问题是,如果在没有这些 DLL 的旧版本 Windows 上使用 DllImport 加载它们,将在运行时导致 DllNotFoundException。

如何捕获/防止/忽略 DllNotFoundExceptions?尝试在我的未处理异常事件中将异常设置为“已处理”不允许应用继续。

【问题讨论】:

  • 异常是在调用点还是在程序加载时抛出(但在您实际尝试调用这些函数之前)?
  • 捕获异常不是最理想的,因为应该避免将异常作为正常应用程序流程的一部分。在您的情况下,在特定平台上,每个调用都会首先抛出一个异常,如果可能的话我会避免。

标签: c# pinvoke dllimport dllnotfoundexception


【解决方案1】:

我认为您应该能够使用 win32 LoadLibrary/GetProcAddress/FreeLibrary 和委托(就像使用回调函数一样)采用“传统”方式。

http://msdn.microsoft.com/en-us/library/d186xcf0.aspx 可能是一个起点...

这应该让你开始:

[DllImport("kernel32.dll", SetLastError=true)]
public static extern IntPtr LoadLibrary(string lpFileName);

[DllImport("kernel32.dll", SetLastError=true)]
static extern bool FreeLibrary(IntPtr hModule);

[DllImport("kernel32.dll", CharSet=CharSet.Ansi, ExactSpelling=true, SetLastError=true)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

然后您声明一个具有要调用的导出的正确签名的委托,并使用 Marshal.GetDelegateForFunctionPointer() 从您从 GetProcAddress 返回的函数指针创建它。

【讨论】:

    【解决方案2】:

    作为一种选择,您可以在 C++/CLI 中编写某种装饰器组件,该组件将使用 LoadLibrary 或静态链接将所有调用转发到 Windows dll,并手动处理这些 dll 的任何缺失。

    【讨论】:

      猜你喜欢
      • 2010-11-12
      • 1970-01-01
      • 2018-11-24
      • 2023-04-10
      • 2011-10-15
      • 1970-01-01
      • 1970-01-01
      • 2012-10-28
      • 1970-01-01
      相关资源
      最近更新 更多