How to detect Windows 64-bit platform with .NET?
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.
Related videos on Youtube
Marc
Updated on February 09, 2021Comments
-
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 over 15 yearsThis won't work - if running in 32-bit .NET Framework 2.0 on 64-bit Windows, it will return 32-bit.
-
Marc over 15 yearsRight I forgot this situation. I've edited the question to mention this as well. Thanks stefan-mg.
-
Bruno Lopes about 15 yearsYou still need to check pointer size first, otherwise it just checks if it's a 32 bit process on a 64 bit system
-
Marbal over 14 yearsThis 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 about 14 yearsThat'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 over 13 yearsMake sure you retrieve the correct localised directory name from the Win32 API instead of hardcoding it.
-
dmihailescu over 13 yearsWhen 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 over 13 yearsIsWow64Process was introduced with Win XP SP2. This code works fine if you require XP SP2 or any newer version.
-
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 about 13 yearsI'd say that's a good idea, but you can't assume a user would never do this for some obscure reason.
-
CMircea about 13 years@user9876, does (or did) anyone still target those antique systems?
-
AMissico almost 13 yearsInstead of Reflector, why not just download the source. Then you get the comments and other "notes".
-
AMissico almost 13 years"C:\Program Files\Microsoft.NET\SDK\v2.0 64bit\LateBreaking\PlatformInvoke\WinAPIs\OSInfo\CS\OSInfoCS.sln"
-
Sebastian Good almost 13 yearsThis is not correct; the platform may be 64 bits but you're still running in 32-bit mode.
-
Joe over 12 yearsThis sample fails to dispose the Process instance returned by Process.GetCurrentProcess().
-
ladenedge over 12 yearsSome 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 over 12 yearsNote that this code is licensed under the Microsoft Public License.
-
Marc over 12 yearsVery 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 over 12 yearsAccording 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 over 12 yearsAlso crashes on an older OS, since
IsWow64Process
doesn't exist. -
Sundypha over 12 yearsWMI version without managed .net? I would like to see that, haven't found it so far
-
Matthew Lock about 12 yearsI don't recommend it but you could get around the localisation issue by expanding the environmental var %ProgramFiles(x86)%
-
Daniel Schlößer about 12 yearsThis doesn't work on non-English XP versions because of localized Program Folders name.
-
Mark Kram almost 12 yearsYour 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 almost 12 yearsYour solution returns the correct value on a MacBook Pro with Intel i7-3720QM microprocessor running Bootcamp using a Widows 7 Ultimate partition. +1
-
Barkah over 11 yearsgreat code, thnx! might want to add
static
to the Properties though :) otherwise worked fine for me, tested 32bit, 32on64, and pure 64bit. -
Hagai L over 11 yearsNope. returned "x86" on my windows 7 pro, 64-bit Operating System.
-
Jim Moriarty over 11 yearsDid 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 about 11 yearsThe CodePlex link seems to be broken.
-
Marc about 11 yearsThanks 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 about 11 yearsJust because you have a 64 bit processor doesn't meant you have a 64 bit os
-
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 almost 11 yearsNice. 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 almost 11 yearsThis 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 almost 11 years@dmihailescu: "Unfortunately this solution is flawed." Well, that's helpful. How is it flawed?
-
Christian Casutt almost 11 yearsi don't have a ProgramFilesX86 property on w7x64 vs.net 2010
-
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 over 10 yearsFYI: 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 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 about 10 yearsput 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 almost 9 yearsThis does not answer the question which specifically says .Net 2.0
-
Zyo over 8 yearsFor geek, internal implementation using IsWow64Process(...) referencesource.microsoft.com/#mscorlib/system/…
-
carefulnow1 almost 8 yearsBut even 64-bit systems have this folder haha
-
Marc over 6 yearsThe 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 over 6 yearsYes, mine is for .net 2.0 too.
-
Cristian Ciupitu about 6 years.NET Core has been released under the MIT license, which means you can read the source code for
Is64BitProcess
andIs64BitOperatingSystem
(links for version 2.0). -
cogumel0 almost 6 yearsAnd 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 almost 6 yearsWhat 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 almost 6 yearsWhat 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 almost 6 yearsJust to add 2 cents, when you run this, and your app is configured to
prefer 32-bit
withAny CPU
as yourPlatform Target
then you will getx86
, but if you untickPrefer 32-bit
it you will then getAMD64
. -
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.