Can't seem to get LoadLibraryA or LoadLibraryW to work in Linqpad 5 or 6
I'm trying to dump some Win32 PE resource strings from some Windows DLLs in Linqpad (both Linqpad 5 and 6, x64 and x86) but I can't seem to get LoadLibrary
to work: it always fails with the Win32Exception
: "The specified module could not be found".
It fails with both direct paths to C:\Windows\SysWow64\shell32.dll
as well as when I copy shell32.dll
to my desktop, and give it another name.
Here's my program:
void Main() { Environment.Is64BitProcess.Dump("Environment.Is64BitProcess"); IntPtr.Size.Dump("IntPtr.Size"); DirectoryInfo desktop = new DirectoryInfo( Environment.GetFolderPath( System.Environment.SpecialFolder.Desktop ) ); /// if( Environment.Is64BitProcess ) { // TODO } else { // https://stackoverflow.com/questions/18522102/loadlibraryw-failing-to-load-dll-in-system32 // https://ofekshilon.com/2013/06/22/entry-point-not-found-and-other-dll-loading-problems/ FileInfo dllFile = new FileInfo( Path.Combine( desktop.FullName, "shell32.dll" ) ); if( !dllFile.Exists ) File.Copy( @"C:\Windows\SysWow64\shell32.dll", dllFile.FullName ); dllFile.Refresh(); NativeMethods.ExtractStringFromDLL( dllFile.FullName, -1 ).Dump(); } } /// <summary>See https://stackoverflow.com/questions/41968416/how-to-extract-string-resource-from-dll</summary> static class NativeMethods { [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] private static extern IntPtr LoadLibraryW([MarshalAs(UnmanagedType.LPStr)]string lpFileName); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)] private static extern int LoadStringW(IntPtr hInstance, int ID, StringBuilder lpBuffer, int nBufferMax); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool FreeLibrary(IntPtr hModule); public static string ExtractStringFromDLL(string file, int number) { IntPtr lib = LoadLibraryW(file); if( lib == IntPtr.Zero ) { throw new Win32Exception(); } try { StringBuilder result = new StringBuilder( capacity: 2048); Int32 ok = LoadStringW( lib, number, result, result.Capacity ); if( ok == 0 ) { throw new InvalidOperationException( "String resource not found: \"" + file + "\": " + number + "." ); } return result.ToString(); } finally { FreeLibrary( lib ); } } }
Is anyone else able to get it to work on their machines?
Comments
Your import for LoadLibraryW looks wrong: the parameter should be UnmanagedType.LPWStr.
Also, in LINQPad 6, you might want to check out .NET Core's NativeLibrary.Load function.
@JoeAlbahari Ahhh, that was it. Thank you!