How to detect Windows 64-bit platform with .NET?

216,305

Solution 1

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;
    }
}

Solution 2

.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.

Solution 3

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

Environment.Is64BitOperatingSystem

See Environment.Is64BitOperatingSystem Property (MSDN).

Solution 4

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;
}

Solution 5

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.

Share:
216,305

Related videos on Youtube

Marc
Author by

Marc

Updated on February 09, 2021

Comments

  • Marc
    Marc over 3 years

    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.

  • David
    David over 15 years
    This won't work - if running in 32-bit .NET Framework 2.0 on 64-bit Windows, it will return 32-bit.
  • Marc
    Marc over 15 years
    Right I forgot this situation. I've edited the question to mention this as well. Thanks stefan-mg.
  • Bruno Lopes
    Bruno Lopes about 15 years
    You still need to check pointer size first, otherwise it just checks if it's a 32 bit process on a 64 bit system
  • Marbal
    Marbal over 14 years
    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.
  • Marc
    Marc about 14 years
    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.
  • Christian Hayter
    Christian Hayter over 13 years
    Make sure you retrieve the correct localised directory name from the Win32 API instead of hardcoding it.
  • dmihailescu
    dmihailescu over 13 years
    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 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.
  • Marc
    Marc over 13 years
    IsWow64Process was introduced with Win XP SP2. This code works fine if you require XP SP2 or any newer version.
  • noobish
    noobish about 13 years
    @dmihailescu, you can just use DoesWin32MethodExist before calling IsWow64Process, which is what the .net 4.0 implementation of is64BitOperatingSystem does.
  • GurdeepS
    GurdeepS about 13 years
    I'd say that's a good idea, but you can't assume a user would never do this for some obscure reason.
  • CMircea
    CMircea about 13 years
    @user9876, does (or did) anyone still target those antique systems?
  • AMissico
    AMissico almost 13 years
    Instead of Reflector, why not just download the source. Then you get the comments and other "notes".
  • AMissico
    AMissico almost 13 years
    "C:\Program Files\Microsoft.NET\SDK\v2.0 64bit\LateBreaking\PlatformInvoke\WinAPIs\OSInfo\CS\OSInfoCS‌​.sln"
  • Sebastian Good
    Sebastian Good almost 13 years
    This is not correct; the platform may be 64 bits but you're still running in 32-bit mode.
  • Joe
    Joe over 12 years
    This sample fails to dispose the Process instance returned by Process.GetCurrentProcess().
  • ladenedge
    ladenedge over 12 years
    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
    ladenedge over 12 years
    Note that this code is licensed under the Microsoft Public License.
  • Marc
    Marc over 12 years
    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)".
  • Polynomial
    Polynomial over 12 years
    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
    Polynomial over 12 years
    Also crashes on an older OS, since IsWow64Process doesn't exist.
  • Sundypha
    Sundypha over 12 years
    WMI version without managed .net? I would like to see that, haven't found it so far
  • Matthew Lock
    Matthew Lock about 12 years
    I don't recommend it but you could get around the localisation issue by expanding the environmental var %ProgramFiles(x86)%
  • Daniel Schlößer
    Daniel Schlößer about 12 years
    This doesn't work on non-English XP versions because of localized Program Folders name.
  • Mark Kram
    Mark Kram almost 12 years
    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
    Mark Kram almost 12 years
    Your solution returns the correct value on a MacBook Pro with Intel i7-3720QM microprocessor running Bootcamp using a Widows 7 Ultimate partition. +1
  • Barkah
    Barkah over 11 years
    great code, thnx! might want to add static to the Properties though :) otherwise worked fine for me, tested 32bit, 32on64, and pure 64bit.
  • Hagai L
    Hagai L over 11 years
    Nope. returned "x86" on my windows 7 pro, 64-bit Operating System.
  • Jim Moriarty
    Jim Moriarty over 11 years
    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.
  • Peter Mortensen
    Peter Mortensen about 11 years
    The CodePlex link seems to be broken.
  • Marc
    Marc about 11 years
    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.
  • David
    David about 11 years
    Just because you have a 64 bit processor doesn't meant you have a 64 bit os
  • Andrew Ensley
    Andrew Ensley about 11 years
    @David This reports the processor architecture of Windows; not the CPU. See detailed explanation starting at "The Code" on this page: andrewensley.com/2009/06/c-detect-windows-os-part-1
  • BrainSlugs83
    BrainSlugs83 almost 11 years
    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.
  • andrew.fox
    andrew.fox almost 11 years
    This code works on .NET (tested on 2.0). Env variables can be accessed by: Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")‌​; Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432")‌​;
  • T.J. Crowder
    T.J. Crowder almost 11 years
    @dmihailescu: "Unfortunately this solution is flawed." Well, that's helpful. How is it flawed?
  • Christian Casutt
    Christian Casutt almost 11 years
    i don't have a ProgramFilesX86 property on w7x64 vs.net 2010
  • basher
    basher over 10 years
    @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.
  • Joel Coehoorn
    Joel Coehoorn over 10 years
    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?
  • Marc
    Marc over 10 years
    -1 as this won't work on localized Windows installations. And it uses VB.net whereas the question is tagged for C#.
  • Chris
    Chris about 10 years
    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!)
  • abbottdev
    abbottdev almost 9 years
    This does not answer the question which specifically says .Net 2.0
  • Zyo
    Zyo over 8 years
    For geek, internal implementation using IsWow64Process(...) referencesource.microsoft.com/#mscorlib/system/…
  • carefulnow1
    carefulnow1 almost 8 years
    But even 64-bit systems have this folder haha
  • Marc
    Marc over 6 years
    The accepted answer was for .NET 2.0. If you're on .NET 4.0 or newer, just use Environment.Is64BitOperatingSystem as you can find in the answer with most votes.
  • John Demetriou
    John Demetriou over 6 years
    Yes, mine is for .net 2.0 too.
  • Cristian Ciupitu
    Cristian Ciupitu about 6 years
    .NET Core has been released under the MIT license, which means you can read the source code for Is64BitProcess and Is64BitOperatingSystem (links for version 2.0).
  • cogumel0
    cogumel0 almost 6 years
    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.
  • Alexandru Dicu
    Alexandru Dicu almost 6 years
    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.
  • cogumel0
    cogumel0 almost 6 years
    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.
  • XAMlMAX
    XAMlMAX almost 6 years
    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.
  • Rajesh Mishra
    Rajesh Mishra over 4 years
    @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.