【问题标题】:LoadLibrary in C# shows annoying error dialog using GetErrorLastC# 中的 LoadLibrary 使用 GetErrorLast 显示烦人的错误对话框
【发布时间】:2020-07-24 12:02:06
【问题描述】:

我有一个小项目,我想批量加载注册表中引用的一些库以读取一些资源。我在加载库 C:\Windows\System32\mmsys.cpl 时遇到问题,这似乎有错误。错误本身不是问题,但我想防止显示任何本机错误对话框。我只想将本机代码中的异常重定向到托管代码的异常。我已经使用 .Net Framework 4.8 和 .Net Core 3.1 以及 Kernel32 中的 LoadLibrary 和 LoadLibraryEx 对此进行了测试,但没有任何成功。我已经测试了其他 *.cpl 库,它们加载正常。

预期: 加载此库会导致托管代码中引发异常 - 不显示错误对话框。

实际: 加载这个库会显示这个烦人的对话框,并在托管代码中引发异常。

[System.Runtime.InteropServices.DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
private static extern System.IntPtr LoadLibrary(string lpFileName);

private static void Main(string[] args)
{
  var resource = @"C:\Windows\System32\mmsys.cpl";
  // var resource = @"C:\Windows\System32\timedate.cpl";
  var lib = LoadLibrary(resource);
  if (lib == System.IntPtr.Zero)
  {
    var errorCode = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
    throw new System.SystemException($"System failed to load library '{resource}' with error {errorCode}");
  }
}

错误对话框:

更新:

这个 sn-p 现在正在为我工​​作:

[System.Runtime.InteropServices.DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
private static extern System.IntPtr LoadLibrary(string lpFileName);

[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern ErrorModes SetErrorMode(ErrorModes uMode);

[System.Flags]
public enum ErrorModes : uint
{
  SYSTEM_DEFAULT = 0x0,
  SEM_FAILCRITICALERRORS = 0x0001,
  SEM_NOALIGNMENTFAULTEXCEPT = 0x0004,
  SEM_NOGPFAULTERRORBOX = 0x0002,
  SEM_NOOPENFILEERRORBOX = 0x8000
}


private static void Main(string[] args)
{
  SetErrorMode(ErrorModes.SEM_FAILCRITICALERRORS);
  var resource = @"C:\Windows\System32\mmsys.cpl";
  // var resource = @"C:\Windows\System32\timedate.cpl";
  var lib = LoadLibrary(resource);
  if (lib == System.IntPtr.Zero)
  {
    var errorCode = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
    throw new System.SystemException($"System failed to load library '{resource}' with error {errorCode}");
  }
}

【问题讨论】:

标签: c# .net-core-3.1 loadlibrary kernel32 .net-4.8


【解决方案1】:

您需要先使用 SEM_NOOPENFILEERRORBOX (0x8000) 调用 SetErrorMode

详情请参阅documentation 中的备注部分:

要启用或禁用加载器在加载 DLL 期间显示的错误消息,请使用 SetErrorMode 函数。

【讨论】:

  • 非常感谢您的快速回答。它非常接近,但非常有帮助。
猜你喜欢
  • 2018-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-16
  • 1970-01-01
  • 1970-01-01
  • 2012-11-16
  • 1970-01-01
相关资源
最近更新 更多