次の方法で共有


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 removed

  • Anonymous
    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. //David

  • Anonymous
    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.aspx

  • Anonymous
    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:

  1. I assume PROCESSOR_ARCHITECTURE i.e. HKLMSYSTEMCurrentControlSetControlSession ManagerEnvironmentPROCESSOR_ARCHITECTURE.
  2. 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 removed

  • Anonymous
    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. //David

  • Anonymous
    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. //David

  • Anonymous
    February 02, 2009
    The comment has been removed

  • Anonymous
    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? //David

  • Anonymous
    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).aspx

  • Anonymous
    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 removed

  • Anonymous
    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 If

  • Anonymous
    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 SysWOW64

  • Anonymous
    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=x64

  • Anonymous
    January 06, 2016
    try this : wmic OS Get OSArchitecture | find "-" or wmic cpu get AddressWidth /value maybe this help