How can I get the informati开发者_高级运维on from a Process handle acquired using OpenProcess whether a Process is 32 or 64 Bit?
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.
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;
}
}
This is C code with some Python involved but it gives you an idea. Here's a polished version:
int is64bit(long pid) {
SYSTEM_INFO sysinfo;
HANDLE hProcess;
BOOL isWow64;
// if OS is not 64 bit, no process will be either
GetNativeSystemInfo(&sysinfo);
if (sysinfo.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_AMD64)
return 0;
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);;
if (hProcess == NULL)
return -1;
if (! IsWow64Process(hProcess, &isWow64)) {
CloseHandle(hProcess);
return -1;
}
CloseHandle(hProcess);
if (isWow64)
return 0;
else
return 1;
}
精彩评论