HOWTO: Detect Process Bitness
In an ideal world, everything runs as native bitness (64bit program on 64bit OS, 32bit program on 32bit OS) and life goes on. However, sometimes you need to run that legacy 32bit program on a 64bit OS and need to configure things a little differently as a result. How can you detect this WOW64 case (32bit program on 64bit OS) and act appropriately?
Detection Matrix
The general idea is to check the following environment variables:
- PROCESSOR_ARCHITECTURE - reports the native processor architecture EXCEPT for WOW64, where it reports x86.
- PROCESSOR_ARCHITEW6432 - not used EXCEPT for WOW64, where it reports the original native processor architecture.
Visually, it looks like:
Environment Variable \ Program Bitness | 32bit Native | 64bit Native | WOW64 |
PROCESSOR_ARCHITECTURE | x86 | AMD64 | x86 |
PROCESSOR_ARCHITEW6432 | undefined | undefined | AMD64 |
- WOW64 = 32bit Program on 64bit OS
- Replace AMD64 with IA64 for Itaniums
Detection Logic
The logic that I use from a program to detect whether the OS is 32bit or 64bit looks like this:
IF PROCESSOR_ARCHITECTURE == amd64 OR
PROCESSOR_ARCHITEW6432 == amd64 THEN
// OS is 64bit
ELSE
// OS is 32bit
END IF
Another way to test for the same thing is:
IF PROCESSOR_ARCHITECTURE == x86 AND
PROCESSOR_ARCHITEW6432 NOT DEFINED THEN
// OS is 32bit
ELSE
// OS is 64bit
END IF
While detection for whether a process is in WOW64 mode is to simply check for the presence of the PROCESSOR_ARCHITEW6432 environment variable.
In Closing...
Now, WHEN would one have to do this? Oh... how about when you are a 32bit application and need to:
- Turn off WOW64 FileSystem Redirection to reach into System32 directory to launch a 64bit process
- Turn off WOW64 Registry Redirection to read the real HKLM\Software or HKCU\Software values
Of course, you should realize that WOW64 is just a compatibility shim and NOT an architecture to build/rely upon, so I would keep these sorts of manipulations to a minimum. Sometimes, it is a good idea to not disturb the man behind the curtain...
//David
Comments
Anonymous
April 09, 2006
You can also check sizeof(PVOID). If you get 8 you're a 64 bit process. If you get 4 then call IsWow64Process to see if you're running in wow64.
This way your code doesn't depend on environment variables (which can be changed by the parent process) and will continue to work if Windows supports new architectures in the future.Anonymous
April 09, 2006
The comment has been removedAnonymous
September 24, 2006
What would be correct way to invoke ml.exe or ml64.exe to compile one source file where that source file has directives to compile differently under ml and ml64?
I can't figure it out for the life of me.Anonymous
August 21, 2007
Hi, Thanks for the Post. I stuck up with the Problem where a 32 bit App on 64 bit read the environment variable "PROCESSOR_ARCHITECTURE" and returned x86 even though the Processor Arch is AMD64. Now i tried your solution and it gave me original arch. Thank you very much for this valuable Post.Anonymous
January 14, 2008
Thx a lot for this valuable post.Anonymous
March 13, 2008
The easiest way to check for OS bitness is to P/Invoke GetSystemWow64Directory, if it returns a value you are on a 64-bit OS, if the returned buffer is 0 you are 32-bit. [DllImport("kernel32.dll")] private static extern uint GetSystemWow64Directory(StringBuilder lpBuffer, uint uSize); internal static byte GetOSBitness() { StringBuilder lpBuffer = new StringBuilder(260); uint uSize = GetSystemWow64Directory(lpBuffer, 260); if (uSize > 0) return 1; //64-bit return 0; //32-bit }Anonymous
March 13, 2008
Mr. Chimes - I think reading the PROCESSOR_ARCHITECTURE and PROCESSOR_ARCHITEW6432 environment variables is way easier in all languages, managed code or native code, on any Windows version going back to Windows 9x. No pInvoke required. No chance of mismatched binding on OS that does not even have GetSystemWow64Directory export. //DavidAnonymous
June 03, 2008
Note : The x64 processor architecture is sometimes referred to as "AMD64", "x86-64", "AMD x86-64" or "Intel64". http://msdn.microsoft.com/en-us/library/cc267757.aspxAnonymous
September 17, 2008
Just to make sure I understand this correctly: In case I'm compiling my application to 64 bit, the PROCESSOR_ARCHITEW6432 isn't relevant for me, and I only need to consider the PROCESSOR_ARCHITECTURE variable, correct? What are the optional values of PROCESSOR_ARCHITECTURE? Can I assume that if it is not "x86" then I'm running on 64 bit processor? (Again, my process was compiled for 64 bit) Thanks! Udi.Anonymous
September 17, 2008
Two more things please if I may:
- I assume PROCESSOR_ARCHITECTURE i.e. HKLMSYSTEMCurrentControlSetControlSession ManagerEnvironmentPROCESSOR_ARCHITECTURE.
- Do you know maybe where does its value come from? Is it a WMI class? If so, which class is it? Again, I really apreciate the help! Udi.
Anonymous
September 18, 2008
The comment has been removedAnonymous
September 21, 2008
I'm sorry David for not explaining myself correctly and fully: I have have an installation process that checks this reg key to determine which version of my application to install (the 32 or 64 bit). I'm asking what kind of values may appear in this key, who's responsible for these values (WMI?), and if it is correct to assume that any value different than "x86" means we're running on a 64 bit machine? Thanks again and sorry for the nag. Udi.Anonymous
September 24, 2008
Udi - I recommend against writing one installer that installs different bitness on the fly. It makes handling bitness more complicated than it needs to be. Just make a 32bit x86 installer and a 64bit x64 installer. For example, if I launch your installer on a 64bit OS while under a WOW64 cmd-shell, should your installer install 32bit, 64bit, both, or neither? And what is the user intention in this scenario? This will remain the classic problem on 64bit OS for many years to come. The answer is trivial with pure 32bit and pure 64bit installer. When you start adding logic, it can backfire. //DavidAnonymous
September 28, 2008
I understand, but when the process should be done automatically - what can you do? Indeed we have two different installation files and one that consists them both which tries to figure out which one to launch according to this key. The user should not be involved in the process. Please let me know in case I missed anything, and if you have an answer to the questions above I'll appreciate it :) Thanks, Udi.Anonymous
September 28, 2008
Udi - I am pointing out the classic problems that people miss. You will have to provide your own answer because it depends on what you want to do. I am just saying that the problem exists only if you have one installer that tries to figure things out. If you have one 32bit and one 64bit installer, it is a non-issue. If you cannot come up with your own answer then you should stick with separate 32bit and 64bit installers. MSI-based installers easily detect bitness and do the right things, so trying to bake it all into one installer means you have to know what you are doing. I just think it is weird for a 32bit SYSWOW process to install 64bit code because it breaks compatibility. //DavidAnonymous
February 02, 2009
The comment has been removedAnonymous
February 16, 2009
Jeff - All of the redirections on 64bit Windows are actually very rational once you understand what it is doing and work with it instead of against it. It only feels frustrating until you know what you are truly doing. The core of your problem is that your batch file is launched by a 32bit command interpreter on 64bit OS which causes you to go down the WOW path when you want to go down the native 64bit path. You have to figure out what is wrong with your unattend install command which kicks it off. I do lots of OS automation/unattend installation using both CScript and Batch files, and they always kick off with the bitness I intend, so your unintended 32bitness issue is most definitely specific with what you are doing. I don't know what exactly you mean by "running in batch as part of the unattend install". Is this from the GUIRunOnce or something else? //DavidAnonymous
January 08, 2010
Unfortunately this doesn't work correctly when 64-bit cmd.exe is executed inside a 32-bit process (e.g. Total Commander does this). This is because environment of a 32-bit program is passed to a 64-bit child process and the detected architecture is x64 running in WOW64 mode. This may cause a lot of confusion. For example, %SystemRoot%Sysnative is not a valid path for 64-bit processes, while it is the only way to reach actual %SystemRoot%System32 on an x64 in WOW64.Anonymous
January 08, 2010
I believe that the only reliable way to tell x86 and AMD64 apart is to check whether %SystemRoot%SysWOW64 folder or alternatively HKLMSoftwareWOW6432Node branch exist.Anonymous
October 31, 2011
David, thanks for the valuable post.Anonymous
February 23, 2012
Robert 9 Jan 2010: > or alternatively HKLMSoftwareWOW6432Node branch exist Not good. That key CAN exist on 32-bit Windows, as a symbolic link to the 32-bit hive. msdn.microsoft.com/.../ms724072(v=vs.85).aspxAnonymous
July 08, 2012
Thank you very much, that help me a lot. How I need a batch script and don't know how use AND, OR I needed make some changes, here works fine, please take a look and tell me if exist some wrong. @ECHO OFF IF /I %PROCESSOR_ARCHITECTURE% == x86 GOTO x86 ECHO your 64bit Native code here ... GOTO END :AMD64 ECHO your WOW64 code here ... GOTO END :x86 IF DEFINED PROCESSOR_ARCHITEW6432 GOTO AMD64 ECHO your 32bit Native code here ... :END pause
If in your application amd64 = wow64 is fine you can more simple: @ECHO OFF IF /I %PROCESSOR_ARCHITECTURE% == x86 GOTO x86 :AMD64 ECHO your 64bit Native and WOW64 code here ... GOTO END :x86 IF DEFINED PROCESSOR_ARCHITEW6432 GOTO AMD64 ECHO your 32bit Native code here ... :END pause
Anonymous
May 28, 2013
The comment has been removedAnonymous
June 17, 2013
Under Windows 7 x64; if you're running cmd from syswow64 folder, it will report as x86, and from system32, as amd64.Anonymous
July 23, 2013
Here is the complete vbScript based on the above article :D 'To Check the System For 32 bit OS or 64 Bit OS On Error Resume Next Dim ProcessArchitectureX86 Dim ProcessArchitectureW6432 Set wshShell = CreateObject("WScript.Shell") ProcessArchitectureX86 = wshShell.ExpandEnvironmentStrings("%PROCESSOR_ARCHITECTURE%") if wshShell.ExpandEnvironmentStrings("%PROCESSOR_ARCHITEW6432%") = "%PROCESSOR_ARCHITEW6432%" Then ProcessArchitectureW6432 = "Not Defined" End If if ProcessArchitectureX86 = "x86" And ProcessArchitectureW6432 = "Not Defined" Then ' For windows 32 bit Else ' For Windows 64 bit End IfAnonymous
March 14, 2014
I found on my Win7x64 system: msgbox wscript.createobject("wscript.shell").environment("system").item("processor_architecture") ' always "AMD64" msgbox wscript.createobject("wscript.shell").environment("process").item("processor_architecture") ' "AMD64" if launched via System32, "x86" if launched via SysWOW64Anonymous
February 23, 2015
Here is a one-liner for batch file that uses David's logic to determine bitness: REM Set WINBIT as 32-bit (x86) or 64-bit (x64) SET WINBIT=x86&&IF "%PROCESSOR_ARCHITECTURE%" == "AMD64" (SET WINBIT=x64) ELSE IF "%PROCESSOR_ARCHITEW6432%" == "AMD64" SET WINBIT=x64Anonymous
January 06, 2016
try this : wmic OS Get OSArchitecture | find "-" or wmic cpu get AddressWidth /value maybe this help