LoadLibraryEx Function Probelem In C#

0

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?

c#
asp.net
asked on Stack Overflow Jul 1, 2020 by Jermine

1 Answer

0

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:

  1. Your program has a referenced to a managed assembly (in the References section under the project in Solution Explorer)
  2. You call Assembly.Load (or one of the variants) from your code, loading in a managed assembly
  3. You use P/Invoke to load an unmanaged DLL and execute a function within it (like how you are loading kernel32.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.

  1. Use LoadLibary(Ex), but with the caveat that you have to do much of the work of (and mimic the actions of) the P/Invoke marshaler. You also can't use this with a managed DLL because 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.

answered on Stack Overflow Jul 1, 2020 by Flydog57 • edited Jul 2, 2020 by Flydog57

User contributions licensed under CC BY-SA 3.0