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!
