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 en
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
See the batch script listed in How To Check If Computer Is Running A 32 Bit or 64 Bit Operating System. It also includes instructions for checking this from the Registry:
You can use the following registry location to check if computer is running 32 or 64 bit of Windows operating system:
HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0
You will see the following registry entries in the right pane:
Identifier REG_SZ x86 Family 6 Model 14 Stepping 12
Platform ID REG_DWORD 0x00000020(32)
The above “x86” and “0x00000020(32)” indicate that the operating system version is 32 bit.
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;
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.
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!