【问题标题】:Detect whether current Windows version is 32 bit or 64 bit检测当前 Windows 版本是 32 位还是 64 位
【发布时间】:2010-10-10 16:59:22
【问题描述】:

信不信由你,我的安装程序太旧了,它没有检测 64 位版本 Windows 的选项。

是否有 Windows DLL 调用或(甚至更好)环境变量可以为 Windows XP 和 Windows Vista 提供该信息?

一种可能的解决方案

我看到 Wikipedia 指出 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 位(这是由 Windows-on-Windows 64 位重定向引起的)。

【问题讨论】:

标签: windows batch-file 64-bit


【解决方案1】:

要在命令框中检查 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 位版本)自动定义的环境变量,仅适用于 Windows 64 位机器。

【讨论】:

  • 你在那里测试的环境变量是什么?通过回答“是,否”,您是否在回答问题:“这是 64 位版本的 Windows”吗?
  • 我刚刚检查了 32 位和 64 位 Windows 7 系统,它的工作原理与宣传的一样。不错。
  • 请注意,if 的大括号在 XP+ 中有效。如果您关心 Win98,那就是 ;-)。
  • 它的使用也很简单,无需任何额外的食谱和诸如 Chef 之类的工具,这是一个额外的好处。
  • 经过测试,我认为这应该是公认的答案。
【解决方案2】:

下面是一些 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;

【讨论】:

  • 由于stackoverflow是一个编程站点,程序员的回答是:使用旨在回答这个问题的API。
  • 有效吗?由于您在编译时测试应用程序是否构建在 64 位系统上。基本上,如果应用程序是在 64 位上编译的,它总是会回答 TRUE,即使是 32 位。我说的对吗?
  • @Altar 不,我正在编译时测试应用程序是否是为 64 位系统构建的。您可以在 64 位系统上编译 32 位程序。
  • blogs.msdn.com/b/oldnewthing/archive/2005/02/01/364563.aspx 和 MSDN 都建议此函数始终在 win32 和 win64 中定义,因此只需执行 IsWow64Process 即可使代码更简单。
【解决方案3】:

我测试了我在问题中建议的解决方案:

针对 Windows 环境变量测试:ProgramW6432

如果不为空,则为 64 位 Windows.W

【讨论】:

  • 您在问题中列出的环境变量是 ProgramW6432。在这里,您列出了 PROCESSOR_ARCHITEW6432。你用的是哪一个?
  • 谢谢安德鲁。我很难发现这个错误:当我有人测试它时;-)。应该是:ProgramW6432。现在修复它。
  • 我的 Vista 64 上没有这些环境变量 (ProgramW6432 PROCESSOR_ARCHITEW6432)。我有 PROCESSOR_ARCHITECTURE,设置为 x86 或 AMD64
  • 谢谢迈克!现在,如果我能弄清楚 Processor_Architecture 是否总是出现在 Win 64 上。
  • @Mike、@total、@Clay:我的 64 位 Vista Enterprise SP2 上确实有 ProgramW6432PROCESSOR_ARCHITEW6432CommonProgramW6432,但仅限于 32 位命令提示符。是否定义这些变量似乎取决于调用进程的位数,而不是操作系统位数。
【解决方案4】:

来自批处理脚本:

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: Detect Process Bitness
  2. GetSystemWow64Directory function

【讨论】:

  • 请注意,我的 64 位 Win7 机器将 PROCESSOR_ARCHITECTURE 设置为 AMD64
【解决方案5】:

请参阅 How To Check If Computer Is Running A 32 Bit or 64 Bit Operating System 中列出的批处理脚本。它还包括从注册表中检查此内容的说明:

您可以使用以下注册表位置来检查计算机运行的是 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位。

【讨论】:

  • 我发现引用的 KB 文章有些令人困惑:他们查看 CPU 是 32 位还是 64 位,并据此确定您运行的是 32 位还是 64 位 Windows?我很确定您可以在 64 位 CPU 上运行 32 位 Windows。或者也许我错过了一些东西..
  • @daniel kullmann:显然密钥将被伪造为 X86,因为 microsoft kb 文章注意到使用 HKLM\SYSTEM\CurrentCongtrolSet\Control\Session Manager\Envirornment 来确定实际的处理器类型。跨度>
  • 关于HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0... - 在 Win7 64 位机器上,我有以下值: Identifier = "Intel64 Family 6 Model 23 Stepping 6", and Platform ID=1 - On一个 WinXP 32 机器(一个 VM),我有以下值: Identifier = "x86 Family 6 Model 26 Stepping 5", and Platform ID=1 这里的重点是not 依赖平台 ID(因为对于 x86,它并不总是 0x00000020)。
  • 在 Win8.1x64 上,Platform ID 不存在。但这里其他关键Platform Specific Field 10x00000002(两个)
  • 拥有 64 位 CPU 并不需要运行 64 位窗口。我有一台 64 位 CPU 但预装了 32 位 Windows 的笔记本电脑。
【解决方案6】:

如果您可以进行 API 调用,请尝试使用 GetProcAddress / GetModuleHandle 来检查是否存在 IsWow64Process,这仅存在于具有 64 位版本的 Windows 操作系统中。

您也可以尝试在 Vista/2008 中使用 ProgramFiles(x86) 环境变量以实现向后兼容性,但我不能 100% 确定 XP-64 或 2003-64。

祝你好运!

【讨论】:

  • PG(x86) 至少在 XP-64 中,而且由于 XP-64 与 2003-64 的关系比 XP 原版更相关,我敢打赌它也在 2003-64 年。跨度>
  • 根据 IsWow64Process 的 MSDN 文章,“请注意,此技术不是检测操作系统是否为 64 位版本的 Windows 的可靠方法,因为当前版本的 32 中的 Kernel32.dll -bit Windows 也包含此功能。”
  • 检查 IsWow64Process 的存在是不可靠的。刚刚在 Windows Xp 32 位上失败了。 IsWow64Process 存在
  • 检查入口点不是可靠的测试,但根据 Raymond Chen 调用该入口点(如果存在)并检查返回值是。如果它不存在或返回 FALSE,则您在 32 位 Windows 上,如果返回 TRUE,则您在 WOW64 下运行,因此在 至少 64 位的 Windows 上运行...
【解决方案7】:

我在登录脚本中使用它来检测 64 位 Windows

if "%ProgramW6432%" == "%ProgramFiles%" goto is64flag

【讨论】:

    【解决方案8】:

    对于检索操作系统或硬件的实际位数(32 或 64)的 VBScript / WMI 单行程序,请查看http://csi-windows.com/toolkit/csi-getosbits

    【讨论】:

      【解决方案9】:

      我不知道您使用的是什么语言,但如果操作系统是 64 位,.NET 具有环境变量 PROCESSOR_ARCHITEW6432

      如果您只想知道您的应用程序是运行 32 位还是 64 位,您可以查看IntPtr.Size。在 32 位模式下运行为 4,在 64 位模式下运行为 8。

      【讨论】:

      • 此选项仅适用于 .net。我需要一个适用于我的安装程序的选项。
      • 如果您强制项目为 32 位(例如 Project->Propterties 并将平台目标更改为 x86),则 IntPtr.Size 值为 4。
      • @Jader:没错。我之前没有意识到我的答案有多模棱两可,但是你一指出就很明显了。为了清楚起见,我编辑了我的答案。
      【解决方案10】:

      我想在此处添加我在 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
      

      【讨论】:

      • Josef,你在 32 位和 64 位机器上测试过这个吗?
      • 我的用途是让我的安装程序表现不同,所以我需要一个返回值。所以我会调用这个脚本,然后让它返回一个值(1 或 0 等)。
      • 对于任何想知道的人,PROCESSOR_ARCHITECTURE 变量似乎随着编译程序而改变。 echo %PROCESSOR_ARCHITECTURE% 在 Windows XP x64 上报告了 AMD64,但是当我使用此变量运行 32 位编译程序时,它返回为 x86
      • @codekoala 这就是检查“%PROCESSOR_ARCHITEW6432%”的原因!该脚本适用于所有 Windows 版本 >= XP,即使在 64 位操作系统上的 32 位 cmd.exe 中调用!
      • @Josef 对,朋友!这是一个神奇的环境变量,当我运行set 时没有出现,但它存在于编译的程序中。傻我。谢谢你让我直截了当!
      【解决方案11】:

      很多答案提到调用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

      【讨论】:

        【解决方案12】:

        我不知道它存在于哪个 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
        

        【讨论】:

          【解决方案13】:

          在 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
          

          【讨论】:

          • 检测应用程序是否为 64 位应用程序。如果您将其强制为 32 位(例如 Project->Propterties 并将平台目标更改为 x86),则返回值为 4。
          • 不是这个问题的答案,这会检测应用程序是否编译为 64 位。
          【解决方案14】:

          我用这个:

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

          它在 Windows XP 上运行,在 Windows XP Professional 64 位和 32 位上进行了测试。

          【讨论】:

            【解决方案15】:

            我知道这是古老的,但这是我用来检测 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
            

            【讨论】:

              【解决方案16】:

              我在 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) 
              

              【讨论】:

                【解决方案17】:

                使用 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)获取和修改的。我已经在 Win7 64 位(在 32 位和 64 位 PowerShell 会话中)和 XP 32 位上对此进行了测试。

                【讨论】:

                  【解决方案18】:

                  最好的方法肯定是检查是否有两个程序文件目录,'Program Files'和'Program Files (x86)' 这种方法的好处是你可以在操作系统没有运行的时候这样做,例如机器启动失败,你想重新安装操作系统

                  【讨论】:

                  • 它们可以被移动和/或重命名。这些只是默认名称。
                  • 你试过了吗?我从未见过没有这些目录的安装
                  【解决方案19】:

                  有趣的是,如果我使用

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

                  我在 32 位和 64 位 ISE 中都获得了 AMD64(在 Win7 64 位上)。

                  【讨论】:

                    【解决方案20】:

                    另一种方式created by 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
                    

                    【讨论】:

                      【解决方案21】:

                      这里有一个更简单的批处理脚本方法

                          @echo off
                      
                          goto %PROCESSOR_ARCHITECTURE%
                      
                          :AMD64
                          echo AMD64
                          goto :EOF
                      
                          :x86 
                          echo x86
                          goto :EOF
                      

                      【讨论】:

                        【解决方案22】:

                        对较新版本的 Windows 的回答

                        今天,我在另一个问题上发布了一些代码,并解释了如何使用适用于 Windows 10 版本 1511 或更高版本以及 Windows Server 2016 的 IsWow64Process2 执行此操作。此外,代码确定进程是 32 位还是 64 位,以及是否进程在WOW64模拟器下运行。

                        我发布答案的主要原因之一是,虽然有几个使用 IsWow64Process2 的建议,但我看到的代码没有显示如何使用。

                        请在此处查看答案:https://stackoverflow.com/a/59377888/1691559

                        【讨论】:

                          【解决方案23】:

                          您可以使用来自 npm 的名为 @wider/utils_where-am-i 的模块。这可以在 Windows 机器和其他地方(如 linux)上的任何 javascript 环境中运行。在 Windows 机器上,它提供一个具有 { os: 'win32' } 或 { os : 'win64' } 的对象。它可以在 wshell、经典 ASP 或 nodeJS 中作为传统的纯 javascript 运行

                          【讨论】:

                            【解决方案24】:

                            检查注册表是否存在 HKLM\SOFTWARE\Wow6432Node - 如果存在,则系统为 64 位 - 32 位,否则。

                            【讨论】:

                            • 我会警告不要在注册表中使用 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node 键的存在——它只需要另一个(不正确的)程序在 32 位操作系统上安装一些东西来导致这种方法失败——这就是我首先找到这个页面的原因!
                            猜你喜欢
                            • 2014-08-04
                            • 1970-01-01
                            • 1970-01-01
                            • 2011-10-26
                            • 1970-01-01
                            • 2020-08-01
                            • 2014-07-04
                            • 1970-01-01
                            • 1970-01-01
                            相关资源
                            最近更新 更多