tags:

views:

65

answers:

2

How can I get the information from a Process handle acquired using OpenProcess whether a Process is 32 or 64 Bit?

+2  A: 

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;
         }
 }
Rupeshit
+1, link to the doc: http://msdn.microsoft.com/en-us/library/ms684139(VS.85).aspx
RC
That's also what i thought at first, but this function just determines if the process runs under WoW64, means a 32Bit process under a 64Bit OS, I tested this with WinXP SP3 and it gave me false because it was a 32Bit Process not running under W0W64.
metafex
+2  A: 

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.

Hans Passant
The only problem with it is that GetNativeSystemInfo according to MSDN is supported from WinXP upwards, regardless of architecture. Also, I don't have a machine without AMD64/EMT64 at hand, but doesn't wProcessorArchitecture correspond to the Processor Architecure and not the one of the System installed?edit: i dunno why you guys make the effort to give .net solutions when i tagged it with C and WinAPI, just saying
metafex
Well, you don't need P/Invoke then. Given that you have the right processor to test this, you can answer your own question in about 10 minutes?
Hans Passant
Okay, checked SYSTEM_INFO.wProcessorArchitecture and it corresponds to the information of the system and not of the cpu, so this solution works, thanks.
metafex
Good. Beware that you *have* to use GetProcAddress() in your C code or your program won't run on early operating systems.
Hans Passant