Определите, является ли текущая версия 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 ответа:
смотрите пакетный скрипт, указанный в Как проверить, если компьютер работает под управлением 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
источники:
Если вы можете делать вызовы 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