I try to use LoadLibraryEx Function to load a xxx.dll
. In ASP.NET CORE Web - MVC application. It can return a right value. But in a ASP.NET Web - Web API application. It return 0x00000000
.But GetLastError()
return 0. Here is my demo code
CODE IN ASP.NET Web - Web API application
[DllImport("kernel32.dll")]
static extern uint GetLastError();
[DllImport("kernel32.dll", EntryPoint = "LoadLibraryEx", SetLastError = true)]
private static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
private static uint LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008;
private static void LoadWin32Library(string libPath)
{
IntPtr moduleHandle = LoadLibraryEx(libPath, IntPtr.Zero, LOAD_WITH_ALTERED_SEARCH_PATH);
uint code = GetLastError();
Console.WriteLine(code);
Console.WriteLine(moduleHandle);
if (moduleHandle == IntPtr.Zero)
throw new Win32Exception(Marshal.GetLastWin32Error());
}
// GET api/values
public IEnumerable<string> Get()
{
String lpFileName = "C:\\Program Files\\dotnet\\shared\\Microsoft.NETCore.App\\2.1.11\\System.dll";
LoadWin32Library(lpFileName);
return new string[] { "value1", "value2" };
}
CODE IN ASP.NET CORE Web - MVC
[DllImport("kernel32.dll")]
static extern uint GetLastError();
[DllImport("kernel32.dll", EntryPoint = "LoadLibraryEx", SetLastError = true)]
private static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
private static uint LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008;
private static void LoadWin32Library(string libPath)
{
IntPtr moduleHandle = LoadLibraryEx(libPath, IntPtr.Zero, LOAD_WITH_ALTERED_SEARCH_PATH);
uint code = GetLastError();
Console.WriteLine(code);
Console.WriteLine(moduleHandle);
if (moduleHandle == IntPtr.Zero)
throw new Win32Exception(Marshal.GetLastWin32Error());
}
public string Index()
{
String lpFileName = "C:\\Program Files\\dotnet\\shared\\Microsoft.NETCore.App\\2.1.11\\System.dll";
LoadWin32Library(lpFileName);
return "This is my default action...";
}
In fact. These two pieces of code are basically the same.But the results are completely different.So. If anybody can help me?
This isn't really an "answer" but it's too involved to be a comment.
You should never need to call LoadLibrary
from managed code
There are three ways DLLs can get loaded into managed code:
Assembly.Load
(or one of the variants) from your code, loading in a managed assemblykernel32.dll
and calling GetLastError
or LoadLibraryEx
in your code)And, for completeness (and on the advice of @SeanSkelly), adding a fourth option that does involve LoadLibary(Ex)
, but with severe restrictions. This is definitely not a recommended option.
GetProcAddress
will always fail on a managed assembly.I have a guess as to why you are getting success in one case and a failure in the other. In one case, you are loading in the same System.dll
that the framework has already loaded, so it just returns a handle to the loaded DLL. In the other, you are loading a different version of System.dll. The unmanaged loader doesn't understand versioning and strong names the way Assembly.Load
does, so it says "hey, I already have a System.dll
and it doesn't match up, so I'm failing your request". But, this is just a guess.
But, it doesn't really matter, you don't need to do this.
User contributions licensed under CC BY-SA 3.0