I totally have no idea how this could happen. I'm trying to get the actual full name of an executable file (the cmd.exe
) using GetModuleFileName
. Debugging shows that GetModuleFileName
outputs the correct path but right at the call to FreeLibrary
, it throws the exception AccessViolationException
:
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Here is the code:
[DllImport("kernel32")]
public static extern IntPtr LoadLibrary(string path);
[DllImport("kernel32")]
public static extern int FreeLibrary(IntPtr hModule);
[DllImport("kernel32.dll", SetLastError = true)]
[PreserveSig]
public static extern uint GetModuleFileName([In] IntPtr hModule,[Out] StringBuilder lpFilename,[In] [MarshalAs(UnmanagedType.U4)] int nSize);
var hm = LoadLibrary("cmd.exe");
if (hm != IntPtr.Zero) {
var s = new StringBuilder();
GetModuleFileName(hm, s, 255);//at here s contains the correct path
FreeLibrary(hm);//the exception throws at here.
}
With some trial, I recognized that it occurs only for x64 (or AnyCPU) platform. If the executable file (to find its full name) is a 32 bit file, the platform should be x86 and then it works OK (although my Windows is 64 bit but the code also works when trying to find "cmd.exe"
with the x86 target platform). However if the executable file is a 64 bit one, the platform should be x64 but the code won't work and throw the exception I mentioned.
The problem is x86 platform built works for 32 bit file but x64 platform built does not work for 64 bit file. So it is very strange. At least x86 built is bug free (because it works expectedly) while x64 built looks like buggy.
I would like to know if this is an expected behavior? You can surely reproduce the problem easily with the provided code together with what I described.
Thank you!