[windows] Detect whether current Windows version is 32 bit or 64 bit

Believe it or not, my installer is so old that it doesn't have an option to detect the 64-bit version of Windows.

Is there a Windows DLL call or (even better) an environment variable that would give that information for Windows XP and Windows Vista?

One possible solution

I see that Wikipedia states that the 64-bit version of Windows XP and Windows Vista have a unique environment variable: %ProgramW6432%, so I'm guessing that'd be empty on 32-bit Windows.

This variable points to Program Files directory, which stores all the installed program of Windows and others. The default on English-language systems is C:\Program Files. In 64-bit editions of Windows (XP, 2003, Vista), there are also %ProgramFiles(x86)% which defaults to C:\Program Files (x86) and %ProgramW6432% which defaults to C:\Program Files. The %ProgramFiles% itself depends on whether the process requesting the environment variable is itself 32-bit or 64-bit (this is caused by Windows-on-Windows 64-bit redirection).

This question is related to windows batch-file 64-bit

The answer is


I used this within a login script to detect 64 bit Windows

if "%ProgramW6432%" == "%ProgramFiles%" goto is64flag


I don't know what language you're using, but .NET has the environment variable PROCESSOR_ARCHITEW6432 if the OS is 64-bit.

If all you want to know is whether your application is running 32-bit or 64-bit, you can check IntPtr.Size. It will be 4 if running in 32-bit mode and 8 if running in 64-bit mode.


Here is a simpler method for batch scripts

    @echo off

    goto %PROCESSOR_ARCHITECTURE%

    :AMD64
    echo AMD64
    goto :EOF

    :x86 
    echo x86
    goto :EOF

Answer for Newer Versions of Windows

Today, I posted some code on another question and an explanation of how to do this with IsWow64Process2 for Windows 10 version 1511 or later and Windows Server 2016. Additionally, the code determines if the process is 32 or 64 bit and whether the process is running under the WOW64 emulator.

One of the main reasons I have posted the answer is because while there were several suggestions to use IsWow64Process2, no code that I saw showed how.

Please see the answer here: https://stackoverflow.com/a/59377888/1691559


In C#:

public bool Is64bit() {
    return Marshal.SizeOf(typeof(IntPtr)) == 8;
}

In VB.NET:

Public Function Is64bit() As Boolean
   If Marshal.SizeOf(GetType(IntPtr)) = 8 Then Return True
   Return False
End Function

I tested the solution I suggested in my question:

Tested for Windows Environment Variable: ProgramW6432

If it's non empty then it's 64 bit Windows.W


From a batch script:

IF PROCESSOR_ARCHITECTURE == x86 AND
   PROCESSOR_ARCHITEW6432 NOT DEFINED THEN
   // OS is 32bit
ELSE
   // OS is 64bit
END IF

Using Windows API:

if (GetSystemWow64Directory(Directory, MaxDirectory) > 0) 
   // OS is 64bit
else
   // OS is 32bit

Sources:

  1. HOWTO: Detect Process Bitness
  2. GetSystemWow64Directory function

Interestingly, if I use

get-wmiobject -class Win32_Environment -filter "Name='PROCESSOR_ARCHITECTURE'"

I get AMD64 in both 32-bit and 64-bit ISE (on Win7 64-bit).


Using Windows Powershell, if the following expression returns true, then it's a 64 bit OS:

(([Array](Get-WmiObject -Class Win32_Processor | Select-Object AddressWidth))[0].AddressWidth -eq 64)

This was taken and modified from: http://depsharee.blogspot.com/2011/06/how-do-detect-operating-system.html (Method #3). I've tested this on Win7 64 bit (in both 32 and 64 bit PowerShell sessions), and XP 32 bit.


I know this is ancient but, here's what I use to detect Win764

On Error Resume Next

Set objWSHShell = CreateObject("WScript.Shell")

strWinVer = objWSHShell.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\BuildLabEx")

If len(strWinVer) > 0 Then
    arrWinVer = Split(strWinVer,".")
    strWinVer = arrWinVer(2)
End If

Select Case strWinVer
Case "x86fre"
strWinVer = "Win7"
Case "amd64fre"
    strWinVer = "Win7 64-bit"
Case Else
    objWSHShell.Popup("OS Not Recognized")
    WScript.Quit
End Select

I use this:

@echo off
if "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
 echo 64 BIT
) else (
 echo 32 BIT
)

It works on Windows XP, tested it on Windows XP Professional Both 64 bit and 32 bit.


I tested the following batch file on Windows 7 x64/x86 and Windows XP x86 and it's fine, but I haven't tried Windows XP x64 yet, but this will probably work:

If Defined ProgramW6432 (Do x64 stuff or end if you are aiming for x86) else (Do x86 stuff or end if you are aiming for x64) 

I want to add what I use in shell scripts (but can easily be used in any language) here. The reason is, that some of the solutions here don't work an WoW64, some use things not really meant for that (checking if there is a *(x86) folder) or don't work in cmd scripts. I feel, this is the "proper" way to do it, and should be safe even in future versions of Windows.

 @echo off
 if /i %processor_architecture%==AMD64 GOTO AMD64
 if /i %PROCESSOR_ARCHITEW6432%==AMD64 GOTO AMD64
    rem only defined in WoW64 processes
 if /i %processor_architecture%==x86 GOTO x86
 GOTO ERR
 :AMD64
    rem do amd64 stuff
 GOTO EXEC
 :x86
    rem do x86 stuff
 GOTO EXEC
 :EXEC
    rem do arch independent stuff
 GOTO END
 :ERR
    rem I feel there should always be a proper error-path!
    @echo Unsupported architecture!
    pause
 :END

To check for a 64-bit version of Windows in a command box, I use the following template:

test.bat:

@echo off
if defined ProgramFiles(x86) (
    @echo yes
    @echo Some 64-bit work
) else (
    @echo no
    @echo Some 32-bit work
)

ProgramFiles(x86) is an environment variable automatically defined by cmd.exe (both 32-bit and 64-bit versions) on Windows 64-bit machines only.


The best way is surely just to check whether there are two program files directories, 'Program Files'and 'Program Files (x86)' The advantage of this method is you can do it when the o/s is not running, for instance if the machine has failed to start and you wish to reinstall the operating system


If you can make API calls, try using GetProcAddress / GetModuleHandle to check for the existence of IsWow64Process which is only present in Windows OS that have 64-bit versions.

You could also try the ProgramFiles(x86) environment variable used in Vista/2008 for backwards compatibility, but I'm not 100% sure about XP-64 or 2003-64.

Good luck!


Here is some Delphi code to check whether your program is running on a 64 bit operating system:

function Is64BitOS: Boolean;
{$IFNDEF WIN64}
type
  TIsWow64Process = function(Handle:THandle; var IsWow64 : BOOL) : BOOL; stdcall;
var
  hKernel32 : Integer;
  IsWow64Process : TIsWow64Process;
  IsWow64 : BOOL;
{$ENDIF}
begin
  {$IFDEF WIN64}
     //We're a 64-bit application; obviously we're running on 64-bit Windows.
     Result := True;
  {$ELSE}
  // We can check if the operating system is 64-bit by checking whether
  // we are running under Wow64 (we are 32-bit code). We must check if this
  // function is implemented before we call it, because some older 32-bit 
  // versions of kernel32.dll (eg. Windows 2000) don't know about it.
  // See "IsWow64Process", http://msdn.microsoft.com/en-us/library/ms684139.aspx
  Result := False;
  hKernel32 := LoadLibrary('kernel32.dll');
  if hKernel32 = 0 then RaiseLastOSError;
  try
    @IsWow64Process := GetProcAddress(hkernel32, 'IsWow64Process');
    if Assigned(IsWow64Process) then begin
      if (IsWow64Process(GetCurrentProcess, IsWow64)) then begin
        Result := IsWow64;
      end
      else RaiseLastOSError;
    end;
  finally
    FreeLibrary(hKernel32);
  end;  
  {$ENDIf}
end;

For a VBScript / WMI one-liner that retrieves the actuals bits number (32 or 64) of the OS or the Hardware, take a look at http://csi-windows.com/toolkit/csi-getosbits


I don't know on which Windows version it exists, but on Windows Vista and later this runs:

Function Is64Bit As Boolean
    Dim x64 As Boolean = System.Environment.Is64BitOperatingSystem
    If x64 Then
       Return true
    Else
       Return false
    End If
End Function

A lot of answers mention calling IsWoW64Process() or related functions. This is not the correct way. You should use GetNativeSystemInfo() which was designed for this purpose. Here's an example:

SYSTEM_INFO info;
GetNativeSystemInfo(&info);

if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
  // It's a 64-bit OS
}

Also see: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724340%28v=vs.85%29.aspx


Check the Registry for the existence of HKLM\SOFTWARE\Wow6432Node - If it's there, the system is 64-bit - 32-bit, otherwise.


Another way created by eGerman that uses PE numbers of compiled executables (does not rely on registry records or environment variables):

@echo off &setlocal


call :getPETarget "%SystemRoot%\explorer.exe"


if "%=ExitCode%" EQU "00008664" (
    echo x64
) else (
    if "%=ExitCode%" EQU "0000014C" (
        echo x32
    ) else (
        echo undefined
    )
)


goto :eof


:getPETarget FilePath
:: ~~~~~~~~~~~~~~~~~~~~~~
:: Errorlevel
::   0 Success
::   1 File Not Found
::   2 Wrong Magic Number
::   3 Out Of Scope
::   4 No PE File
:: ~~~~~~~~~~~~~~~~~~~~~~
:: =ExitCode
::   CPU identifier

setlocal DisableDelayedExpansion
set "File=%~1"
set Cmp="%temp%\%random%.%random%.1KB"
set Dmp="%temp%\%random%.%random%.dmp"

REM write 1024 times 'A' into a temporary file
if exist "%File%" (
  >%Cmp% (
    for /l %%i in (1 1 32) do <nul set /p "=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
  )
  setlocal EnableDelayedExpansion
) else (endlocal &cmd /c exit 0 &exit /b 1)

REM generate a HEX dump of the executable file (first 1024 Bytes)
set "X=1"
>!Dmp! (
  for /f "skip=1 tokens=1,2 delims=: " %%i in ('fc /b "!File!" !Cmp!^|findstr /vbi "FC:"') do (
    set /a "Y=0x%%i"
    for /l %%k in (!X! 1 !Y!) do echo 41
    set /a "X=Y+2"
    echo %%j
  )
)
del !Cmp!

REM read certain values out of the HEX dump
set "err="
<!Dmp! (
  set /p "A="
  set /p "B="
  REM magic number has to be "MZ"
  if "!A!!B!" neq "4D5A" (set "err=2") else (
    REM skip next 58 bytes
    for /l %%i in (3 1 60) do set /p "="
    REM bytes 61-64 contain the offset to the PE header in little endian order
    set /p "C="
    set /p "D="
    set /p "E="
    set /p "F="
    REM check if the beginning of the PE header is part of the HEX dump
    if 0x!F!!E!!D!!C! lss 1 (set "err=3") else (
      if 0x!F!!E!!D!!C! gtr 1018 (set "err=3") else (
        REM skip the offset to the PE header
        for /l %%i in (65 1 0x!F!!E!!D!!C!) do set /p "="
        REM next 4 bytes have to contain the signature of the PE header
        set /p "G="
        set /p "H="
        set /p "I="
        set /p "J="
        REM next 2 bytes contain the CPU identifier in little endian order
        set /p "K="
        set /p "L="
      )
    )
  )
)
del !Dmp!
if defined err (endlocal &endlocal &cmd /c exit 0 &exit /b %err%)

REM was the signature ("PE\0\0") of the PE header found
if "%G%%H%%I%%J%"=="50450000" (
  REM calculate the decimal value of the CPU identifier
  set /a "CPUID=0x%L%%K%"
) else (endlocal &endlocal &cmd /c exit 0 &exit /b 4)
endlocal &endlocal &cmd /c exit %CPUID% &exit /b 0

Examples related to windows

"Permission Denied" trying to run Python on Windows 10 A fatal error occurred while creating a TLS client credential. The internal error state is 10013 How to install OpenJDK 11 on Windows? I can't install pyaudio on Windows? How to solve "error: Microsoft Visual C++ 14.0 is required."? git clone: Authentication failed for <URL> How to avoid the "Windows Defender SmartScreen prevented an unrecognized app from starting warning" XCOPY: Overwrite all without prompt in BATCH Laravel 5 show ErrorException file_put_contents failed to open stream: No such file or directory how to open Jupyter notebook in chrome on windows Tensorflow import error: No module named 'tensorflow'

Examples related to batch-file

'ls' is not recognized as an internal or external command, operable program or batch file '' is not recognized as an internal or external command, operable program or batch file XCOPY: Overwrite all without prompt in BATCH CanĀ“t run .bat file under windows 10 Execute a batch file on a remote PC using a batch file on local PC Windows batch - concatenate multiple text files into one How do I create a shortcut via command-line in Windows? Getting Error:JRE_HOME variable is not defined correctly when trying to run startup.bat of Apache-Tomcat Curl not recognized as an internal or external command, operable program or batch file Best way to script remote SSH commands in Batch (Windows)

Examples related to 64-bit

Android Studio: /dev/kvm device permission denied How to printf a 64-bit integer as hex? Unable to install Android Studio in Ubuntu I cannot start SQL Server browser Class not registered Error Excel VBA Code: Compile Error in x64 Version ('PtrSafe' attribute required) MSOnline can't be imported on PowerShell (Connect-MsolService error) How to know installed Oracle Client is 32 bit or 64 bit? The application was unable to start correctly (0xc000007b) How to specify 64 bit integers in c