I have some older code that doesn’t appear to work on 64bit Windows 7. Not tried 32bit Windows 7, but definitely works on 32bit XP.
The code was originally derived from this article http://www.codeproject.com/KB/cs/DynamicInvokeCSharp.aspx
I’ve read this question which states that kernel32.dll still exists.
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
private static extern int LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);
[DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]
private static extern IntPtr GetProcAddress(int hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName);
[DllImport("kernel32.dll", EntryPoint = "FreeLibrary")]
private static extern bool FreeLibrary(int hModule);
[DllImport("kernel32.dll")]
private static extern bool SetDllDirectory([M
arshalAs(UnmanagedType.LPStr)] string lpPathName);
And this is how it is used:
public void Init(string dllName)
{
DllName = dllName;
SetDllDirectory(Path.GetDirectoryName(dllName));
hModule = LoadLibrary(Path.GetFileName(dllName));
if (hModule == 0)
throw new Exception("Cannot load dll " + dllName);
}
The problem I get is that LoadLibrary always returns 0 for the handle.
I have also tried hModule = LoadLibrary(dllName);
Can anyone throw any light on why it might not work, or what I should be doing instead?
(As per comments on the answer)
The majority of Windows API functions call a routine called
SetLastError()to indicate failure reasons. When usingDllImportfrom .NET you can add a property to the attribute to explicitly indicate a function should preserve this last error (I’m not 100% sure on the default behaviour, but being explicit guarantees it will happen).Eg:
You can then get the error code from managed code by calling
Marshal.GetLastWin32Error(), or get a slightly more useful exception by throwing aWin32Exceptionas suchthrow new Win32Exception(Marshal.GetLastWin32Error())