How to determine programmatically whether a particular process is 32-bit or 64-bit
Asked Answered
K

7

114

How can my C# application check whether a particular application/process (note: not the current process) is running in 32-bit or 64-bit mode?

For example, I might want to query a particular process by name, i.e, abc.exe, or based on the process ID number.

Kremlin answered 23/12, 2009 at 15:18 Comment(0)
C
196

One of the more interesting ways I've seen is this:

if (IntPtr.Size == 4)
{
    // 32-bit
}
else if (IntPtr.Size == 8)
{
    // 64-bit
}
else
{
    // The future is now!
}

To find out if OTHER processes are running in the 64-bit emulator (WOW64), use this code:

namespace Is64Bit
{
    using System;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Runtime.InteropServices;

    internal static class Program
    {
        private static void Main()
        {
            foreach (var p in Process.GetProcesses())
            {
                try
                {
                    Console.WriteLine(p.ProcessName + " is " + (p.IsWin64Emulator() ? string.Empty : "not ") + "32-bit");
                }
                catch (Win32Exception ex)
                {
                    if (ex.NativeErrorCode != 0x00000005)
                    {
                        throw;
                    }
                }
            }

            Console.ReadLine();
        }

        private static bool IsWin64Emulator(this Process process)
        {
            if ((Environment.OSVersion.Version.Major > 5)
                || ((Environment.OSVersion.Version.Major == 5) && (Environment.OSVersion.Version.Minor >= 1)))
            {
                bool retVal;

                return NativeMethods.IsWow64Process(process.Handle, out retVal) && retVal;
            }

            return false; // not on 64-bit Windows Emulator
        }
    }

    internal static class NativeMethods
    {
        [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool IsWow64Process([In] IntPtr process, [Out] out bool wow64Process);
    }
}
Carden answered 23/12, 2009 at 15:24 Comment(8)
(Environment.OSVersion.Version.Major >= 5 && Environment.OSVersion.Version.Minor >= 1) And that is why Microsoft has to create version lie compatibility shims - to work around bugs in code like that. What happens when Windows Vista (6.0) comes out? And people then bad-mouth Microsoft for making Windows 7 version 6.1 rather than 7.0, it fixes so many app-compat bugs.Petuntse
the [Out] out bool wow64Process should be [Out] out Int32 wow64Process because the native function's BOOL maps to Int32Joelie
@赵如飞: no. It's a pointer to a boolean. The authoritative source: msdn.microsoft.com/en-us/library/ms684139Carden
Function name IsWin64 is a bit misleading, I think. It returns true if 32-bit process is running under x64 OS.Unlicensed
Why use processHandle = Process.GetProcessById(process.Id).Handle; instead of just processHandle = process.Handle; ?Concoff
@JonathonReinhart well isn't that just a good question. I have no idea. It must have been vestigial from a switching around of doing things one way to another. Thanks for finding that!Carden
This answer is just incorrect; and returning false instead of raising an exception in a case of error is a very bad design.Pepi
It is used for only 64Bit system.This logic fail in 32 Bit SystemMonostich
C
156

If you're using .Net 4.0, it's a one-liner for the current process:

Environment.Is64BitProcess

See Environment.Is64BitProcessProperty (MSDN).

Centavo answered 11/8, 2010 at 18:22 Comment(5)
Could you post the code of Is64BitProcess? Perhaps i can use what it does to figure out if i'm running in as a 64-bit process.Petuntse
@Ian, I doubt Sam would be legally permitted to post MS code on this forum. I'm not sure of the exact content of their reference licence, but I am pretty sure it proscribes reproduction of the code anywhere.Detrimental
@Ian someone has done that work for you: #337133Anorak
The OP specifically asked to query another process, not the current process.Lorenzen
Note that Microsoft did post the code for Is64BitProcess ( referencesource.microsoft.com/#mscorlib/system/environment.cs). However, it's just a hard-coded return statement, controlled by compilation symbol.Summersummerhouse
P
24

The selected answer is incorrect as it doesn't do what was asked. It checks if a process is a x86 process running on x64 OS instead; so it will return "false" for a x64 process on x64 OS.
Also, it doesn't handle errors correctly.

Here is a more correct method:

internal static class NativeMethods
{
    // see https://msdn.microsoft.com/en-us/library/windows/desktop/ms684139%28v=vs.85%29.aspx
    public static bool Is64Bit(Process process)
    {
        if (!Environment.Is64BitOperatingSystem)
            return false;
        // if this method is not available in your version of .NET, use GetNativeSystemInfo via P/Invoke instead

        bool isWow64;
        if (!IsWow64Process(process.Handle, out isWow64))
            throw new Win32Exception();
        return !isWow64;
    }

    [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool IsWow64Process([In] IntPtr process, [Out] out bool wow64Process);
}
Pepi answered 19/10, 2015 at 3:26 Comment(1)
Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE") == "x86" will always return true for a 32bit process. Better to use System.Environment.Is64BitOperatingSystem if .NET4 is supportedFrication
C
11

You can check the size of a pointer to determine if it's 32bits or 64bits.

int bits = IntPtr.Size * 8;
Console.WriteLine( "{0}-bit", bits );
Console.ReadLine();
Clareta answered 23/12, 2009 at 15:27 Comment(1)
At the time this answer was first posted it wasn't very clear, but the OP wanted to know how to query another process rather than the current process.Lorenzen
P
5
[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool lpSystemInfo);

public static bool Is64Bit()
{
    bool retVal;

    IsWow64Process(Process.GetCurrentProcess().Handle, out retVal);

    return retVal;
}
Pratincole answered 13/8, 2013 at 14:22 Comment(2)
The OP specifically asked how to query another process, not the current process.Lorenzen
@HarryJohnston that code is valid with little change to get "other" process not current process, like Process.GetProcessesByName("otherprocess.exe").First().Handle, but using IsWow64Process from kernel32 is an important part here!Unipod
B
2

Here is the one line check.

bool is64Bit = IntPtr.Size == 8;
Bewley answered 9/5, 2013 at 9:8 Comment(1)
The OP specifically asked how to query another process, not the current process.Lorenzen
C
0

I like to use this:

string e = Environment.Is64BitOperatingSystem

This way if I need to locate or verify a file I can easily write:

string e = Environment.Is64BitOperatingSystem

       // If 64 bit locate the 32 bit folder
       ? @"C:\Program Files (x86)\"

       // Else 32 bit
       : @"C:\Program Files\";
Cineaste answered 13/7, 2012 at 12:26 Comment(3)
what about 32bit process in 64bit OS Machine ?Hornbeam
Is it really so hard to use Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) instead of hard-coding `C:\Program Files`?Spatial
Never hard-code "program files", because it's a localizable string. Αρχεία Εφαρμογών, Arquivos de Programas, etc.Bohman

© 2022 - 2024 — McMap. All rights reserved.