it-swarm.com.ru

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

Верьте или нет, мой установщик настолько стар, что у него нет возможности обнаружить 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).

61
Clay Nichols

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

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

HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0

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

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

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

9
Leif Gruenwoldt

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

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) - это переменная среды, автоматически определяемая cmd.exe (как 32-разрядная, так и 64-разрядная версии) только на 64-разрядных компьютерах Windows.

62
Dror Harari

Вот некоторый код 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;
20
Blorgbeard

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

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

Если он не пустой, то это 64-битная Windows.W

13
Clay Nichols

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

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. HOWTO: Определить разрядность процесса
  2. функция GetSystemWow64Directory
13
Leif Gruenwoldt

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

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

Удачи!

8
Jason

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

if "% ProgramW6432%" == "% ProgramFiles%" Перейти к is64flag

6
TallGuy

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

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

4
Andrew Ensley

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

4
Darwin

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

Во многих ответах упоминается вызов 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

3
jcoffland

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

В 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
1
Renaud Bompuis

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

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

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

1
user83250

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

0
jasee

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

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

    @echo off

    goto %PROCESSOR_ARCHITECTURE%

    :AMD64
    echo AMD64
    goto :EOF

    :x86 
    echo x86
    goto :EOF
0
Max

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

Используя 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-битной.

0
CJBS

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

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

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

0
Mike Shepard

Другой способ созданный 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
npocmaka