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:
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}");
}
}
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
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP