Определить, является ли текущая версия Windows 32-битной или 64-битной - PullRequest
61 голосов
/ 02 марта 2009

Верьте или нет, мой установщик настолько стар, что у него нет возможности определять 64-разрядную версию Windows.

Есть ли в Windows вызов DLL или (что еще лучше) переменная среды, которая выдала бы эту информацию для Windows XP и Windows Vista?

Одно из возможных решений

Я вижу, что Википедия утверждает, что 64-разрядная версия Windows XP и Windows Vista имеет уникальную переменную среды: %ProgramW6432%, поэтому я предполагаю, что она будет пустой в 32-разрядной Windows.

Эта переменная указывает на каталог Program Files, в котором хранятся все установленные программы Windows и другие. По умолчанию в англоязычных системах используется C:\Program Files. В 64-разрядных выпусках Windows (XP, 2003, Vista) также есть %ProgramFiles(x86)%, по умолчанию C:\Program Files (x86) и %ProgramW6432%, по умолчанию C:\Program Files. Сам %ProgramFiles% зависит от того, является ли процесс, запрашивающий переменную среды, самим 32-разрядным или 64-разрядным (это вызвано 64-разрядным перенаправлением Windows-on-Windows).

Ответы [ 22 ]

3 голосов
/ 08 июля 2012

Я хочу добавить то, что я использую в сценариях оболочки (но может легко использоваться на любом языке) здесь. Причина в том, что некоторые решения здесь не работают с WoW64, некоторые используют вещи, которые на самом деле не предназначены для этого (проверка наличия папки * (x86)), или не работают в сценариях cmd. Я считаю, что это «правильный» способ сделать это и должен быть безопасным даже в будущих версиях 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
2 голосов
/ 02 февраля 2011

Я не знаю, в какой версии Windows она существует, но в Windows Vista и более поздних версиях она работает:

Function Is64Bit As Boolean
    Dim x64 As Boolean = System.Environment.Is64BitOperatingSystem
    If x64 Then
       Return true
    Else
       Return false
    End If
End Function
1 голос
/ 09 января 2015

Я использую это:

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

Работает на Windows XP, протестировано на Windows XP Professional. И 64-битная, и 32-битная.

1 голос
/ 02 марта 2009

В C #:

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

В VB.NET :

Public Function Is64bit() As Boolean
   If Marshal.SizeOf(GetType(IntPtr)) = 8 Then Return True
   Return False
End Function
0 голосов
/ 02 января 2012

Я протестировал следующий пакетный файл на Windows 7 x64 / x86 и Windows XP x86, и это нормально, но я еще не пробовал Windows XP x64, но это, вероятно, будет работать:

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) 
0 голосов
/ 20 ноября 2014

Вот более простой метод для пакетных сценариев

    @echo off

    goto %PROCESSOR_ARCHITECTURE%

    :AMD64
    echo AMD64
    goto :EOF

    :x86 
    echo x86
    goto :EOF
0 голосов
/ 20 августа 2014

Другой способ , созданный eGerman , который использует числа PE скомпилированных исполняемых файлов (не полагается на записи реестра или переменные среды):

@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
0 голосов
/ 09 июля 2014

Интересно, если я использую

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

Я получаю AMD64 как в 32-битном, так и в 64-битном ISE (в Win7 64-битный).

0 голосов
/ 25 апреля 2014

Лучше всего, конечно, просто проверить, есть ли две директории программных файлов: «Program Files» и «Program Files (x86)». Преимущество этого метода в том, что вы можете сделать это, когда операционная система не работает, например, если машина не запустилась и вы хотите переустановить операционную систему

0 голосов
/ 22 января 2014

Используя Windows Powershell, если следующее выражение возвращает true, тогда это 64-битная ОС:

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

Это было взято и изменено с: http://depsharee.blogspot.com/2011/06/how-do-detect-operating-system.html (Метод № 3). Я проверил это на 64-битной Win7 (как в 32-, так и в 64-битной сессиях PowerShell) и 32-битной XP.

...