How can I get the information from a Process handle acquired using OpenProcess whether a Process is 32 or 64 Bit?
You can test it using following code:
bool is64BitProcess = (IntPtr.Size == 8);
bool is64BitOperatingSystem = is64BitProcess || InternalCheckIsWow64();
[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWow64Process(
[In] IntPtr hProcess,
[Out] out bool wow64Process
);
[MethodImpl(MethodImplOptions.NoInlining)]
private static bool InternalCheckIsWow64()
{
if ((Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) ||
Environment.OSVersion.Version.Major >= 6)
{
using (Process p = Process.GetCurrentProcess())
{
bool retVal;
if (!IsWow64Process(p.Handle, out retVal))
{
return false;
}
return retVal;
}
}
else
{
return false;
}
}
Yes, IsWow64Process is annoyingly useless. It really means "is 32-bit emulation enabled" and that returns false if you run on a 32-bit operating system, it doesn't need any emulation.
You'll only get a good value out of it if you know for a fact that you're running on a 64-bit operating system. Which is tricky to find out. The IntPtr.Size == 8 test proofs that you run 64-bit, but it doesn't proof that it is definitely not a 64-bit operating system. The 64-bit version of the framework might not have been installed. Or your code might be running from an .exe that had the Platform Target forced to x86. Which is not uncommon for code that's interested in bitness.
You'll need to P/Invoke GetNativeSystemInfo(). If that throws (or GetProcAddress returns IntPtr.Zero), you know for a fact that it is a 32-bit operating system. If it doesn't, inspect the value of SYSTEM_INFO.wProcessorArchitecture. It will be 9 for x64, 6 for Titanium, 0 for x86. So if you get 9, then use IsWow64Process. Visit pinvoke.net for the declarations.
Note that the new .NET 4.0 Environment.Is64BitOperatingSystem is flawed the same way.