Определите, является ли текущая версия Windows 32-разрядной или 64-разрядной


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

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

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

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

эта переменная указывает на 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 61

22 ответа:

смотрите пакетный скрипт, указанный в Как проверить, если компьютер работает под управлением 32-разрядной или 64-разрядной операционной системы. Она также включает в себя инструкции для проверки этого из реестра:

вы можете использовать следующее расположение реестра, чтобы проверить, если компьютер работает 32 или 64 бит операционной системы Windows:

HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor

вы увидите следующие записи реестра в правой панели:

Identifier     REG_SZ             x86 Family 6 Model 14 Stepping 12
Platform ID    REG_DWORD          0x00000020(32)

выше "x86" и "0x00000020 (32)" указывает, что версия операционной системы 32 бит.

чтобы проверить наличие 64-разрядной версии Windows в командной строке, я использую следующий шаблон:

вот некоторые Delphi код, чтобы проверить, работает ли ваша программа на 64-разрядной операционной системе:

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;

Я проверил решение, которое я предложил в моем вопросе:

проверено для переменной среды Windows: ProgramW6432

Если он не пустой, то это 64-битные окна.Вт

из пакетного сценария:

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

Использование Windows API:

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

источники:

  1. методические указания: определить процесс разрядности
  2. GetSystemWow64Directory function

Если вы можете делать вызовы API, попробуйте использовать GetProcAddress/GetModuleHandle чтобы проверить наличие IsWow64Process, которая присутствует только в ОС Windows, которые имеют 64-разрядные версии.

вы также можете попробовать ProgramFiles (x86) переменная окружения, используемая в Vista / 2008 Для обратной совместимости, но я не уверен на 100% в XP-64 или 2003-64.

удачи!

Я использовал это в сценарии входа для обнаружения 64-битных окон

Если" %ProgramW6432% "= = "%ProgramFiles% " goto is64flag

на VBScript и WMI, в один-лайнер, который получает фактические данные количество битов (32 или 64) операционной системы или аппаратного обеспечения, взгляните на http://csi-windows.com/toolkit/csi-getosbits

Я не знаю, какой язык вы используете, но .NET имеет переменную окружения PROCESSOR_ARCHITEW6432 Если ОС 64-разрядная.

Если все, что вы хотите знать, является ли ваше приложение работает 32-бит или 64-бит, вы можете проверить IntPtr.Size. Это будет 4, если работает в 32-битном режиме и 8, если работает в 64-битном режиме.

Я хочу добавить то, что я использую в скриптах оболочки (но может быть легко использован на любом языке) здесь. Причина в том, что некоторые из решений здесь не работают с 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

Я не знаю, на какой версии 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

многие ответы упоминают вызов IsWoW64Process() или взаимосвязанные функции. Это не правильно путь. Вы должны использовать GetNativeSystemInfo() который был разработан для этой цели. Вот пример:

SYSTEM_INFO info;
GetNativeSystemInfo(&info);

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

Также см.: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724340%28v=vs.85%29.aspx

В 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

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

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

он работает на Windows XP, протестировал его на Windows XP Professional как 64 бит, так и 32 бит.

Я знаю, что это древний, но вот что я использую для обнаружения 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

я протестировал следующий пакетный файл на 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) 

С помощью 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) и XP 32 бит.

лучший способ, конечно, просто проверить, есть ли два каталога program files, "Program Files" и " Program Files (x86)" Преимущество этого метода заключается в том, что вы можете сделать это, когда o/s не работает, например, если машина не запустилась, и вы хотите переустановить операционную систему

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

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

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

другой способ создано эгерманом который использует 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") 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

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

    @echo off

    goto %PROCESSOR_ARCHITECTURE%

    :AMD64
    echo AMD64
    goto :EOF

    :x86 
    echo x86
    goto :EOF

Проверьте реестр на наличие HKLM\SOFTWARE\Wow6432Node - Если он есть, то система 64-битная - 32-бит, в противном случае.