295

In a .NET 2.0 C# application I use the following code to detect the operating system platform:

string os_platform = System.Environment.OSVersion.Platform.ToString();

This returns "Win32NT". The problem is that it returns "Win32NT" even when running on Windows Vista 64-bit.

Is there any other method to know the correct platform (32 or 64 bit)?

Note that it should also detect 64 bit when run as a 32 bit application on Windows 64 bit.

John Demetriou
  • 4,093
  • 6
  • 52
  • 88
Marc
  • 9,012
  • 13
  • 57
  • 72

31 Answers31

258

.NET 4 has two new properties in the Environment class, Is64BitProcess and Is64BitOperatingSystem. Interestingly, if you use Reflector you can see they are implemented differently in the 32-bit & 64-bit versions of mscorlib. The 32-bit version returns false for Is64BitProcess and calls IsWow64Process via P/Invoke for Is64BitOperatingSystem. The 64-bit version just returns true for both.

Phil Devaney
  • 17,607
  • 6
  • 41
  • 33
  • 5
    Instead of Reflector, why not just download the source. Then you get the comments and other "notes". – AMissico Jul 25 '11 at 16:39
  • 3
    According to the reference source, it does something like this: `if (IntPtr.Size == 8) return true; if(!DoesWin32MethodExist(...,"IsWow64Process")) return false; return IsWow64Process(GetCurrentProcess());` (pseudo-code) – Polynomial Jan 19 '12 at 22:33
  • 5
    Nice. If the user is using .NET 4.0 this is definitely the correct answer (i.e. Environment.Is64BitOperatingSystem). -- FYI property does not appear to be there in .NET 3.5. – BrainSlugs83 May 30 '13 at 00:49
  • 5
    This does not answer the question which specifically says .Net 2.0 – abbottdev Jul 24 '15 at 08:43
  • .NET Core has been released under the MIT license, which means you can read the source code for [`Is64BitProcess`](https://github.com/dotnet/corefx/blob/dev/release/2.0.0/src/System.Runtime.Extensions/src/System/Environment.cs#L152) and [`Is64BitOperatingSystem`](https://github.com/dotnet/corefx/blob/dev/release/2.0.0/src/System.Runtime.Extensions/src/System/Environment.cs#L154) (links for version 2.0). – Cristian Ciupitu Feb 16 '18 at 06:09
234

UPDATE: As Joel Coehoorn and others suggest, starting at .NET Framework 4.0, you can just check Environment.Is64BitOperatingSystem.


IntPtr.Size won't return the correct value if running in 32-bit .NET Framework 2.0 on 64-bit Windows (it would return 32-bit).

As Microsoft's Raymond Chen describes, you have to first check if running in a 64-bit process (I think in .NET you can do so by checking IntPtr.Size), and if you are running in a 32-bit process, you still have to call the Win API function IsWow64Process. If this returns true, you are running in a 32-bit process on 64-bit Windows.

Microsoft's Raymond Chen: How to detect programmatically whether you are running on 64-bit Windows

My solution:

static bool is64BitProcess = (IntPtr.Size == 8);
static bool is64BitOperatingSystem = is64BitProcess || InternalCheckIsWow64();

[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsWow64Process(
    [In] IntPtr hProcess,
    [Out] out bool wow64Process
);

public 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;
    }
}
Stefan Schultze
  • 9,240
  • 6
  • 35
  • 42
  • 8
    When running on a 32 bit OS, any call to IsWow64Process will throw an exception since that entry is missing from kernel32.dll. You should check the solution shown from codeplex at http://1code.codeplex.com/SourceControl/changeset/view/39074#842775 .I also have a solution based on that code listed at the bottom of this page, that uses extension methods if you care about reusing the code. – dmihailescu Feb 02 '11 at 18:29
  • 8
    IsWow64Process was introduced with Win XP SP2. This code works fine if you require XP SP2 or any newer version. – Marc Feb 04 '11 at 09:12
  • 3
    @dmihailescu, you can just use DoesWin32MethodExist before calling IsWow64Process, which is what the .net 4.0 implementation of is64BitOperatingSystem does. – noobish Mar 18 '11 at 23:04
  • 4
    Your solution returns the correct value on a MacBook Pro with Intel i7-3720QM microprocessor running Bootcamp using a Widows 7 Ultimate partition. +1 – Mark Kram Jul 15 '12 at 00:40
  • 3
    great code, thnx! might want to add `static` to the Properties though :) otherwise worked fine for me, tested 32bit, 32on64, and pure 64bit. – Damian Vogel Aug 22 '12 at 13:10
  • 1
    @dmihailescu: *"Unfortunately this solution is flawed."* Well, that's helpful. **How** is it flawed? – T.J. Crowder Jun 24 '13 at 09:17
  • @T.J.Crowder dmihailescu answered that in his second comment and subsequent answer to OP's question. I'm not saying he's right or wrong - just saying he answered it. "Unfortunately this solution is flawed" is a pretty awful comment, though. – basher Aug 29 '13 at 13:40
  • 14
    FYI: starting with .Net 4.0 you can just check `System.Environment.Is64BitOperatingSystem`. Can you edit this into your answer, or give me permission to edit it into your answer? – Joel Coehoorn Nov 21 '13 at 15:01
104

If you're using .NET Framework 4.0, it's easy:

Environment.Is64BitOperatingSystem

See Environment.Is64BitOperatingSystem Property (MSDN).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 2
    For geek, internal implementation using IsWow64Process(...) http://referencesource.microsoft.com/#mscorlib/system/environment.cs,75feca36cdd83149 – Zyo Nov 29 '15 at 04:04
51

This is just an implementation of what's suggested above by Bruno Lopez, but works on Win2k + all WinXP service packs. Just figured I'd post it so other people didn't have roll it by hand. (would have posted as a comment, but I'm a new user!)

[DllImport("kernel32", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
public extern static IntPtr LoadLibrary(string libraryName);

[DllImport("kernel32", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
public extern static IntPtr GetProcAddress(IntPtr hwnd, string procedureName);

private delegate bool IsWow64ProcessDelegate([In] IntPtr handle, [Out] out bool isWow64Process);

public static bool IsOS64Bit()
{
    if (IntPtr.Size == 8 || (IntPtr.Size == 4 && Is32BitProcessOn64BitProcessor()))
    {
        return true;
    }
    else
    {
        return false;
    }
}

private static IsWow64ProcessDelegate GetIsWow64ProcessDelegate()
{
  IntPtr handle = LoadLibrary("kernel32");

  if ( handle != IntPtr.Zero)
  {
    IntPtr fnPtr = GetProcAddress(handle, "IsWow64Process");

    if (fnPtr != IntPtr.Zero)
    {
      return (IsWow64ProcessDelegate)Marshal.GetDelegateForFunctionPointer((IntPtr)fnPtr, typeof(IsWow64ProcessDelegate));
    }
  }

  return null;
}

private static bool Is32BitProcessOn64BitProcessor()
{
  IsWow64ProcessDelegate fnDelegate = GetIsWow64ProcessDelegate();

  if (fnDelegate == null)
  {
    return false;
  }

  bool isWow64;
  bool retVal = fnDelegate.Invoke(Process.GetCurrentProcess().Handle, out isWow64);

  if (retVal == false)
  {
    return false;
  }

  return isWow64;
}
dwhiteho
  • 636
  • 5
  • 4
49

The full answer is this (taken from both stefan-mg, ripper234 and BobbyShaftoe's answer):

    [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool lpSystemInfo);

    private bool Is64Bit()
    {
        if (IntPtr.Size == 8 || (IntPtr.Size == 4 && Is32BitProcessOn64BitProcessor()))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    private bool Is32BitProcessOn64BitProcessor()
    {
        bool retVal;

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

        return retVal;
    } 

First check if you're in a 64 bit process. If you're not, check if the 32 bit process is a Wow64Process.

Bruno Lopes
  • 2,917
  • 1
  • 27
  • 38
  • 13
    This will fail under Win2000 and WinXP SP1 and earlier. You need to check if the IsWow64Process() function exists before you call it, because it was only introduced in XP SP2 and Vista/Win7. – user9876 Nov 16 '09 at 12:19
  • 2
    @user9876, does (or did) anyone still target those antique systems? – CMircea Apr 26 '11 at 20:58
  • 5
    This sample fails to dispose the Process instance returned by Process.GetCurrentProcess(). – Joe Sep 09 '11 at 18:20
43

Microsoft has put a code sample for this:

http://1code.codeplex.com/SourceControl/changeset/view/39074#842775

It looks like this:

    /// <summary>
    /// The function determines whether the current operating system is a 
    /// 64-bit operating system.
    /// </summary>
    /// <returns>
    /// The function returns true if the operating system is 64-bit; 
    /// otherwise, it returns false.
    /// </returns>
    public static bool Is64BitOperatingSystem()
    {
        if (IntPtr.Size == 8)  // 64-bit programs run only on Win64
        {
            return true;
        }
        else  // 32-bit programs run on both 32-bit and 64-bit Windows
        {
            // Detect whether the current process is a 32-bit process 
            // running on a 64-bit system.
            bool flag;
            return ((DoesWin32MethodExist("kernel32.dll", "IsWow64Process") &&
                IsWow64Process(GetCurrentProcess(), out flag)) && flag);
        }
    }

    /// <summary>
    /// The function determins whether a method exists in the export 
    /// table of a certain module.
    /// </summary>
    /// <param name="moduleName">The name of the module</param>
    /// <param name="methodName">The name of the method</param>
    /// <returns>
    /// The function returns true if the method specified by methodName 
    /// exists in the export table of the module specified by moduleName.
    /// </returns>
    static bool DoesWin32MethodExist(string moduleName, string methodName)
    {
        IntPtr moduleHandle = GetModuleHandle(moduleName);
        if (moduleHandle == IntPtr.Zero)
        {
            return false;
        }
        return (GetProcAddress(moduleHandle, methodName) != IntPtr.Zero);
    }

    [DllImport("kernel32.dll")]
    static extern IntPtr GetCurrentProcess();

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr GetModuleHandle(string moduleName);

    [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
    static extern IntPtr GetProcAddress(IntPtr hModule,
        [MarshalAs(UnmanagedType.LPStr)]string procName);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process);

There is a WMI version available as well (for testing remote machines).

synhershko
  • 4,472
  • 1
  • 30
  • 37
17

You can also check for the PROCESSOR_ARCHITECTURE environment variable.

It either doesn't exist or is set to "x86" on 32-bit Windows.

private int GetOSArchitecture()
{
    string pa = 
        Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
    return ((String.IsNullOrEmpty(pa) || 
             String.Compare(pa, 0, "x86", 0, 3, true) == 0) ? 32 : 64);
}
Andrew Ensley
  • 11,611
  • 16
  • 61
  • 73
  • 1
    Just because you have a 64 bit processor doesn't meant you have a 64 bit os – David May 09 '13 at 07:22
  • 2
    @David This reports the processor architecture of Windows; not the CPU. See detailed explanation starting at "The Code" on this page: http://andrewensley.com/2009/06/c-detect-windows-os-part-1/ – Andrew Ensley May 09 '13 at 21:02
  • 1
    Just to add 2 cents, when you run this, and your app is configured to `prefer 32-bit` with `Any CPU` as your `Platform Target` then you will get `x86`, but if you untick `Prefer 32-bit` it you will then get `AMD64`. – XAMlMAX Aug 10 '18 at 12:32
17

From Chriz Yuen blog

C# .Net 4.0 Introduced two new environment property Environment.Is64BitOperatingSystem; Environment.Is64BitProcess;

Please be careful when you use these both property. Test on Windows 7 64bits Machine

//Workspace: Target Platform x86
Environment.Is64BitOperatingSystem True
Environment.Is64BitProcess False

//Workspace: Target Platform x64
Environment.Is64BitOperatingSystem True
Environment.Is64BitProcess True

//Workspace: Target Platform Any
Environment.Is64BitOperatingSystem True
Environment.Is64BitProcess True
electricalbah
  • 2,227
  • 2
  • 22
  • 36
15

Quickest way:

if(IntPtr.Size == 8) {
    // 64 bit machine
} else if(IntPtr.Size == 4)  {
    // 32 bit machine
} 

Note: this is very direct and works correctly on 64-bit only if the program does not force execution as a 32-bit process (e.g. through <Prefer32Bit>true</Prefer32Bit> in the project settings).

Pierre Arnaud
  • 10,212
  • 11
  • 77
  • 108
BobbyShaftoe
  • 28,337
  • 7
  • 52
  • 74
11

Try this:

Environment.Is64BitOperatingSystem

Environment.Is64BitProcess
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user2235582
  • 147
  • 1
  • 2
  • 5
    Thanks for your input, but please read the available answers before posting as this solution is already given. Also note that the original question was about .net 2 which doesn't have these two properties which were introduced only with .net 4. – Marc Apr 09 '13 at 06:13
10

@foobar: You are right, it is too easy ;)

In 99% of the cases, developers with weak system administrator backgrounds ultimately fail to realize the power Microsoft has always provided for anyone to enumerate Windows.

System administrators will always write better and simpler code when it comes to such a point.

Nevertheless, one thing to note, build configuration must be AnyCPU for this environment variable to return the correct values on the correct systems:

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")

This will return "X86" on 32-bit Windows, and "AMD64" on 64-bit Windows.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
SomeSysadmin
  • 109
  • 1
  • 2
  • 4
    Your solution returns x86 on a MacBook Pro with Intel i7-3720QM microprocessor running Bootcamp with a Widows 7 Ultimate partition. Stefan Schultze's solution properly Identified the processor as a 64 bit. I'm sure that you solution works on 99% of the Windows based pc out there. +1 for trying. – Mark Kram Jul 15 '12 at 00:39
  • 1
    Nope. returned "x86" on my windows 7 pro, 64-bit Operating System. – Hagai L Dec 24 '12 at 13:55
8

Using dotPeek helps to see how the framework actually does it. With that in mind, here's what I've come up with:

public static class EnvironmentHelper
{
    [DllImport("kernel32.dll")]
    static extern IntPtr GetCurrentProcess();

    [DllImport("kernel32.dll")]
    static extern IntPtr GetModuleHandle(string moduleName);

    [DllImport("kernel32")]
    static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

    [DllImport("kernel32.dll")]
    static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process);

    public static bool Is64BitOperatingSystem()
    {
        // Check if this process is natively an x64 process. If it is, it will only run on x64 environments, thus, the environment must be x64.
        if (IntPtr.Size == 8)
            return true;
        // Check if this process is an x86 process running on an x64 environment.
        IntPtr moduleHandle = GetModuleHandle("kernel32");
        if (moduleHandle != IntPtr.Zero)
        {
            IntPtr processAddress = GetProcAddress(moduleHandle, "IsWow64Process");
            if (processAddress != IntPtr.Zero)
            {
                bool result;
                if (IsWow64Process(GetCurrentProcess(), out result) && result)
                    return true;
            }
        }
        // The environment must be an x86 environment.
        return false;
    }
}

Example usage:

EnvironmentHelper.Is64BitOperatingSystem();
Alexandru
  • 12,264
  • 17
  • 113
  • 208
6

Use these two environment variables (pseudo code):

if (PROCESSOR_ARCHITECTURE = x86 &&
    isDefined(PROCESSOR_ARCHITEW6432) &&
    PROCESSOR_ARCHITEW6432 = AMD64) {

    //64 bit OS
}
else
    if (PROCESSOR_ARCHITECTURE = AMD64) {
        //64 bit OS
    }
    else
        if (PROCESSOR_ARCHITECTURE = x86) {
            //32 bit OS
        }

Refer to the blog post HOWTO: Detect Process Bitness.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Santhosh
  • 6,547
  • 15
  • 56
  • 63
  • Did you see the part where the question was about .NET and not C/C++? And that this is a compile time versus a runtime check. Also, the code is doing assignment and not comparisons. – dvallejo Jan 11 '13 at 22:22
  • This code works on .NET (tested on 2.0). Env variables can be accessed by: Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"); Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432"); – andrew.fox Jun 07 '13 at 09:10
5

I used this check with success on many operating systems:

private bool Is64BitSystem
{
   get
   {
      return Directory.Exists(Environment.ExpandEnvironmentVariables(@"%windir%\SysWOW64"));
   }
}

This folder is always named "SysWOW64", no matter of the language of the operating system. This works for .NET Framework 1.1 or above.

Alexandru Dicu
  • 1,151
  • 1
  • 16
  • 24
  • And what prevents me as a user with administrative rights from creating a folder called `SysWOW64` on a `%windir%` on a 32 bit OS? The presence of a folder means exactly that: that the folder is present. – cogumel0 Jun 13 '18 at 12:15
  • What are the chances that a user will create such a folder on purpose? This is just a different way to check if the operating system is x64. – Alexandru Dicu Jul 10 '18 at 11:25
  • What are the chances that your computer will get a virus? Since the chances are quite low, better not install any protection then... Programming is not about creating something that that has low chances of *knowingly* failing. It's about creating something that that has low chances of *unknowingly* failing - and then fixing it. The first is called bad programming/bad implementation, the second is called a bug. – cogumel0 Jul 23 '18 at 15:47
  • @AlexandruDicu You should mention in the answer that this approach is not 100% accurate and still risk of giving wrong output in case the folder is created on purpose by any third party app or user manually. – Rajesh Mishra Oct 15 '19 at 07:22
4

This is a solution based on Microsoft's code at http://1code.codeplex.com/SourceControl/changeset/view/39074#842775. It uses extension methods for easy code reuse.

Some possible usage is shown below:

bool bIs64BitOS = System.Environment.OSVersion.IsWin64BitOS();

bool bIs64BitProc = System.Diagnostics.Process.GetCurrentProcess().Is64BitProc();

//Hosts the extension methods  
public static class OSHelperTools  
{  
    /// <summary>     
    /// The function determines whether the current operating system is a      
    /// 64-bit operating system.     
    /// </summary>     
    /// <returns>     
    /// The function returns true if the operating system is 64-bit;      
    /// otherwise, it returns false.     
    /// </returns>    
    public static bool IsWin64BitOS(this OperatingSystem os)  
    {  
        if (IntPtr.Size == 8)  
        // 64-bit programs run only on Win64           
            return true;   
        else// 32-bit programs run on both 32-bit and 64-bit Windows     
        {   // Detect whether the current process is a 32-bit process                
            // running on a 64-bit system.               
            return Process.GetCurrentProcess().Is64BitProc();  
        }  
    }  

    /// <summary>  
    /// Checks if the process is 64 bit  
    /// </summary>  
    /// <param name="os"></param>  
    /// <returns>  
    /// The function returns true if the process is 64-bit;        
    /// otherwise, it returns false.  
    /// </returns>    
    public static bool Is64BitProc(this System.Diagnostics.Process p)  
    {  
        // 32-bit programs run on both 32-bit and 64-bit Windows           
        // Detect whether the current process is a 32-bit process                
        // running on a 64-bit system.               
        bool result;  
        return ((DoesWin32MethodExist("kernel32.dll", "IsWow64Process") && IsWow64Process(p.Handle, out result)) && result);  
    }  

    /// <summary>     
    /// The function determins whether a method exists in the export      
    /// table of a certain module.     
    /// </summary>     
    /// <param name="moduleName">The name of the module</param>     
    /// <param name="methodName">The name of the method</param>     
    /// <returns>     
    /// The function returns true if the method specified by methodName      
    /// exists in the export table of the module specified by moduleName.     
    /// </returns>       
    static bool DoesWin32MethodExist(string moduleName, string methodName)  
    {  
        IntPtr moduleHandle = GetModuleHandle(moduleName);  
        if (moduleHandle == IntPtr.Zero)  
            return false;    
        return (GetProcAddress(moduleHandle, methodName) != IntPtr.Zero);   
    }  
    [DllImport("kernel32.dll")]  
    static extern IntPtr GetCurrentProcess();  

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]  
    static extern IntPtr GetModuleHandle(string moduleName);  

    [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]  
    static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)]string procName);  

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]  
    [return: MarshalAs(UnmanagedType.Bool)]  
    static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process);  
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
dmihailescu
  • 1,625
  • 17
  • 15
4

I need to do this, but I also need to be able as an admin do it remotely, either case this seems to work quite nicely for me:

    public static bool is64bit(String host)
    {
        using (var reg = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, host))
        using (var key = reg.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\"))
        {
            return key.GetValue("ProgramFilesDir (x86)") !=null;
        }
    }
3

Here is the direct approach in C# using DllImport from this page.

[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; 
} 
ripper234
  • 222,824
  • 274
  • 634
  • 905
3

I'm using the followin code. Note: It's made for an AnyCPU project.

    public static bool Is32bitProcess(Process proc) {
        if (!IsThis64bitProcess()) return true; // We're in 32-bit mode, so all are 32-bit.

        foreach (ProcessModule module in proc.Modules) {
            try {
                string fname = Path.GetFileName(module.FileName).ToLowerInvariant();
                if (fname.Contains("wow64")) {
                    return true;
                }
            } catch {
                // What on earth is going on here?
            }
        }
        return false;
    }

    public static bool Is64bitProcess(Process proc) {
        return !Is32bitProcess(proc);
    }

    public static bool IsThis64bitProcess() {
        return (IntPtr.Size == 8);
    }
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
blez
  • 4,939
  • 5
  • 50
  • 82
2

All fine, but this should also work from env:

PROCESSOR_ARCHITECTURE=x86

..

PROCESSOR_ARCHITECTURE=AMD64

Too easy, maybe ;-)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
2

I found this to be the best way to check for the platform of the system and the process:

bool 64BitSystem = Environment.Is64BitOperatingSystem;
bool 64BitProcess = Environment.Is64BitProcess;

The first property returns true for 64-bit system, and false for 32-bit. The second property returns true for 64-bit process, and false for 32-bit.

The need for these two properties is because you can run 32-bit processes on 64-bit system, so you will need to check for both the system and the process.

OmarElsherif
  • 177
  • 1
  • 4
  • 2
    put a _ or a letter in front of the variable name if you want it to build in c# (variable names dont start with numbers in c# as far as my ide is telling me!) – Chris May 05 '14 at 17:27
2

Here's a Windows Management Instrumentation (WMI) approach:

string _osVersion = "";
string _osServicePack = "";
string _osArchitecture = "";

ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from Win32_OperatingSystem");
ManagementObjectCollection collection = searcher.Get();

foreach (ManagementObject mbo in collection)
{
    _osVersion = mbo.GetPropertyValue("Caption").ToString();
    _osServicePack = string.Format("{0}.{1}", mbo.GetPropertyValue("ServicePackMajorVersion").ToString(), mbo.GetPropertyValue("ServicePackMinorVersion").ToString());

    try
    {
        _osArchitecture = mbo.GetPropertyValue("OSArchitecture").ToString();
    }
    catch
    {
        // OSArchitecture only supported on Windows 7/Windows Server 2008
    }
}

Console.WriteLine("osVersion     : " + _osVersion);
Console.WriteLine("osServicePack : " + _osServicePack);
Console.WriteLine("osArchitecture: " + _osArchitecture);

/////////////////////////////////////////
// Test on Windows 7 64-bit
//
// osVersion     : Microsoft Windows 7 Professional
// osservicePack : 1.0
// osArchitecture: 64-bit

/////////////////////////////////////////
// Test on Windows Server 2008 64-bit
//    --The extra r's come from the registered trademark
//
// osVersion     : Microsoftr Windows Serverr 2008 Standard
// osServicePack : 1.0
// osArchitecture: 64-bit

/////////////////////////////////////////
// Test on Windows Server 2003 32-bit
//    --OSArchitecture property not supported on W2K3
//
// osVersion     : Microsoft(R) Windows(R) Server 2003, Standard Edition
// osServicePack : 2.0
// osArchitecture:
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user1054695
  • 101
  • 1
  • 2
1

OSInfo.Bits

using System;
namespace CSharp411
{
    class Program
    {
        static void Main( string[] args )
        {
           Console.WriteLine( "Operation System Information" );
           Console.WriteLine( "----------------------------" );
           Console.WriteLine( "Name = {0}", OSInfo.Name );
           Console.WriteLine( "Edition = {0}", OSInfo.Edition );
           Console.WriteLine( "Service Pack = {0}", OSInfo.ServicePack );
           Console.WriteLine( "Version = {0}", OSInfo.VersionString );
           Console.WriteLine( "Bits = {0}", OSInfo.Bits );
           Console.ReadLine();
        }
    }
}
Scott Dorman
  • 42,236
  • 12
  • 79
  • 110
Greg
  • 11
  • 1
  • 3
    That's all nice, but this class is from Microsoft.UpdateServices.Administration namespace which is Microsoft WSUS. I don't like to include this reference just to know the platform bits. – Marc Apr 22 '10 at 14:10
  • "C:\Program Files\Microsoft.NET\SDK\v2.0 64bit\LateBreaking\PlatformInvoke\WinAPIs\OSInfo\CS\OSInfoCS.sln" – AMissico Jul 25 '11 at 17:09
1

Include the following code into a class in your project:

    [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool wow64Process);

    public static int GetBit()
    {
        int MethodResult = "";
        try
        {
            int Architecture = 32;

            if ((Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) || Environment.OSVersion.Version.Major >= 6)
            {
                using (Process p = Process.GetCurrentProcess())
                {
                    bool Is64Bit;

                    if (IsWow64Process(p.Handle, out Is64Bit))
                    {
                        if (Is64Bit)
                        {
                            Architecture = 64;

                        }

                    }

                }

            }

            MethodResult = Architecture;

        }
        catch //(Exception ex)
        {
            //ex.HandleException();
        }
        return MethodResult;
    }

Use it like so:

string Architecture = "This is a " + GetBit() + "bit machine";
WonderWorker
  • 8,539
  • 4
  • 63
  • 74
0

Use this to get the installed Windows architecture:

string getOSArchitecture()
{
    string architectureStr;
    if (Directory.Exists(Environment.GetFolderPath(
                           Environment.SpecialFolder.ProgramFilesX86))) {
        architectureStr ="64-bit";
    }
    else {
        architectureStr = "32-bit";
    }
    return architectureStr;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user885959
  • 55
  • 1
0

Given that the accepted answer is very complex. There are simpler ways. Mine is a variation of alexandrudicu's anaswer. Given that 64-bit windows install 32-bit applications in Program Files (x86) you can check if that folder exists, using environment variables (to make up for different localizations)

e.g.

private bool Is64BitSystem
{
   get
   {
      return Directory.Exists(Environment.ExpandEnvironmentVariables(@"%PROGRAMFILES(X86)%"));
   }
}

This for me is faster and simpler. Given that I also wish to access a specific path under that folder based on OS version.

John Demetriou
  • 4,093
  • 6
  • 52
  • 88
0

This question is for .NET 2.0 but still comes up in a google search, and nobody here mentionned that since .NET standard 1.1 / .NET core 1.0, there is now a better way to know the CPU architecture:

System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture

This should theoretically be able to differenciate between x64 and Arm64, though I didn't test it myself.

See the documentation.

cube45
  • 3,429
  • 2
  • 24
  • 35
0

Sorry for code of VB.NET, but it easy to port to C#. It works ok on Win7, x64 with .Net Framework 4.8:

Dim r As String = ""
Using searcher As ManagementObjectSearcher = New System.Management.ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem")
    Dim Information As ManagementObjectCollection = searcher.Get()
    If Information IsNot Nothing Then
        For Each obj As ManagementObject In Information
            r = obj("Caption").ToString() & _
            " - " & _
            obj("OSArchitecture").ToString() ' <--- !!! "64-bit" shown here
        Next
    End If
    MessageBox.Show(r)
End Using
AndyCODE
  • 111
  • 1
  • 5
-2

Enjoy ;-)

Function Is64Bit() As Boolean

    Return My.Computer.FileSystem.SpecialDirectories.ProgramFiles.Contains("Program Files (x86)")

End Function
Majid95
  • 23
  • -1 as this won't work on localized Windows installations. And it uses VB.net whereas the question is tagged for C#. – Marc Dec 04 '13 at 15:27
-3

Just see if the "C:\Program Files (x86)" exists. If not, then you are on a 32 bit OS. If it does, then the OS is 64 bit (Windows Vista or Windows 7). It seems simple enough...

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
John
  • 9
  • 5
    Make sure you retrieve the correct localised directory name from the Win32 API instead of hardcoding it. – Christian Hayter Sep 17 '10 at 08:42
  • I'd say that's a good idea, but you can't assume a user would never do this for some obscure reason. – GurdeepS Apr 02 '11 at 22:27
  • 2
    Some poorly-written applications are now installing directly to "Program Files (x86)" without regard to architecture. I have that directory on my 32-bit machine thanks to SOAPSonar, for example. – ladenedge Sep 12 '11 at 16:18
-4

I use:

Dim drivelet As String = Application.StartupPath.ToString
If Directory.Exists(drivelet(0) & ":\Program Files (x86)") Then
    MsgBox("64bit")
Else
    MsgBox("32bit")
End if

This gets the path where your application is launched in case you have it installed in various places on the computer. Also, you could just do the general C:\ path since 99.9% of computers out there have Windows installed in C:\.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ben G
  • 9
  • 8
    Very bad approach. What if in the future this directory will be renamed? What about localized version of Windows? In Windows XP German "Program Files" is called "Programme". I'm not sure but XP 64 may thus call it "Programme (x86)". – Marc Nov 14 '11 at 12:16
  • 1
    I don't recommend it but you could get around the localisation issue by expanding the environmental var %ProgramFiles(x86)% – Matthew Lock Apr 02 '12 at 07:58
-7

I use a version of the following:

    public static bool Is64BitSystem()
    {
        if (Directory.Exists(Environment.GetEnvironmentVariable("Program Files (x86)"))) return true;
        else return false;
    }
AMissico
  • 21,470
  • 7
  • 78
  • 106
Josh
  • 37
  • 1
  • 1
  • 3