TransWikia.com

LoadLibrary in C# shows annoying error dialog using GetErrorLast

Stack Overflow Asked by Borckla on December 27, 2021

I have a little project, where I want to bulk load some libraries referenced in the registry to read some resources. I get stuck on loading the library C:WindowsSystem32mmsys.cpl, which seems to have errors. The error itself is not the problem, but I want to prevent showing any native error dialog. I just want to redirect the exception in the native code to a exception of the managed code. I have tested this with .Net Framework 4.8 and .Net Core 3.1 as well as LoadLibrary and LoadLibraryEx in Kernel32 without any success. I have tested other *.cpl libraries and they are loading fine.

Expected:
Loading this library causes an exception thrown in the managed code – no error dialog is shown.

Actual:
Loading this library shows this annoying dialog as well as throwing the exception in the managed code.

[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:WindowsSystem32mmsys.cpl";
  // var resource = @"C:WindowsSystem32timedate.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}");
  }
}

The error dialog:

The error dialog

Update:

This snippet is now working for me:

[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:WindowsSystem32mmsys.cpl";
  // var resource = @"C:WindowsSystem32timedate.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}");
  }
}

One Answer

You need to call first SetErrorMode with SEM_NOOPENFILEERRORBOX (0x8000).

See the Remarks section in the documentation for details:

To enable or disable error messages displayed by the loader during DLL loads, use the SetErrorMode function.

Answered by Nick on December 27, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP