检测当前的Windows版本是32位还是64位
信不信由你,我的安装程序太老了,它没有一个选项来检测64位版本的Windows。
有没有一个Windows DLL调用或(甚至更好)一个环境variables,将为Windows XP和Windows Vista的信息?
一个可能的scheme
我看到维基百科指出,64位版本的Windows XP和Windows Vista有一个独特的环境variables: %ProgramW6432%
,所以我猜测在32位Windows上是空的。
这个variables指向Program Files
目录,它存储了所有已安装的Windows及其他程序。 英文系统的默认值是C:\Program Files
。 在Windows(XP,2003,Vista)的64位版本中,还有%ProgramFiles(x86)%
默认为C:\Program Files (x86)
和%ProgramW6432%
,默认为C:\Program Files
。 %ProgramFiles%
本身取决于请求环境variables的进程本身是32位还是64位(这是由Windows-on-Windows 64位redirect引起的)。
请参阅如何检查计算机是否正在运行32位或64位操作系统中列出的批处理脚本。 它还包括从registry中检查的说明:
您可以使用以下registry位置来检查计算机是否正在运行32位或64位的Windows操作系统:
HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0
您将在右窗格中看到以下registry项:
Identifier REG_SZ x86 Family 6 Model 14 Stepping 12 Platform ID REG_DWORD 0x00000020(32)
上面的“x86”和“0x00000020(32)”表示操作系统版本是32位。
要在命令框中检查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)
是由Windows 64位机器上的cmd.exe(32位和64位版本)自动定义的环境variables。
这里有一些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;
我testing了我在我的问题中提出的解决scheme:
testingWindows环境variables:ProgramW6432
如果它不是空的,那么它是64位的Windows.W
从批处理脚本:
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
资料来源:
- HOWTO:检测进程比特率
- GetSystemWow64Directory函数
如果您可以进行API调用,请尝试使用GetProcAddress / GetModuleHandle检查是否存在仅在具有64位版本的Windows操作系统中存在的IsWow64Process 。
您也可以尝试在Vista / 2008中使用的ProgramFiles(x86)环境variables,以实现向后兼容性,但对于XP-64或2003-64,我并不十分确定。
祝你好运!
我在一个login脚本中使用这个来检测64位的Windows
如果“%ProgramW6432%”==“%ProgramFiles%”goto is64flag
对于检索操作系统或硬件的实际位数(32或64)的VBScript / WMI单行程序,请查看http://csi-windows.com/toolkit/csi-getosbits
我不知道你在用什么语言,但是如果操作系统是64位的, .NET的环境variables是PROCESSOR_ARCHITEW6432
。
如果你想知道的是你的应用程序是否运行32位或64位,你可以检查IntPtr.Size
。 如果以32位模式运行,则为4;如果以64位模式运行,则为8。
我想在这里添加我在shell脚本中使用的东西(但可以很容易地用于任何语言)。 原因是,这里的一些解决scheme不能用于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()
或相关函数。 这不是正确的方法。 您应该使用为此目的而devise的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; }
在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位上进行testing。
我知道这是古老的,但这是我用来检测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上testing了以下batch file,这很好,但是我还没有尝试过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,如果下面的expression式返回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)。 我已经testing了Win7 64位(32位和64位PowerShell会话)和XP 32位。
最好的办法就是检查是否有两个程序文件目录,'Program Files'和'Program Files(x86)'这个方法的优点是你可以在o / s不运行的时候执行,例如if机器启动失败,您希望重新安装操作系统
有趣的是,如果我使用
get-wmiobject -class Win32_Environment -filter "Name='PROCESSOR_ARCHITECTURE'"
我在32位和64位ISE(Win7 64位)上都使用了AMD64。
eGerman创build的另一种使用PE编号的可执行文件(不依赖于registrylogging或环境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
这是批处理脚本的一个更简单的方法
@echo off goto %PROCESSOR_ARCHITECTURE% :AMD64 echo AMD64 goto :EOF :x86 echo x86 goto :EOF
检查registry是否存在HKLM \ SOFTWARE \ Wow6432Node – 如果存在,系统是64位 – 32位,否则。