【问题标题】:How can I use VBScript to determine whether I am running a 32-bit or 64-bit Windows OS?如何使用 VBScript 来确定我运行的是 32 位还是 64 位 Windows 操作系统?
【发布时间】:2023-03-08 04:42:02
【问题描述】:

如何在 VBScript 中检测 Windows 操作系统的位数(32 位与 64 位)?

我尝试了这种方法,但它不起作用;我猜 (x86) 导致了一些检查文件夹的问题..

还有其他选择吗?

progFiles="c:\program files" & "(" & "x86" & ")"

set fileSys=CreateObject("Scripting.FileSystemObject")

If fileSys.FolderExists(progFiles) Then    
   WScript.Echo "Folder Exists"    
End If

【问题讨论】:

标签: windows vbscript 32bit-64bit


【解决方案1】:

前几天在工作中遇到了同样的问题。偶然发现了这个天才的 vbscript,觉得太好了,不分享了。

Bits = GetObject("winmgmts:root\cimv2:Win32_Processor='cpu0'").AddressWidth

来源:http://csi-windows.com/toolkit/csi-getosbits

【讨论】:

  • +1.49 - 不错的解决方案 - 但是 - 唉 - 在 WMI 时间上工作(以茶杯为单位)。
【解决方案2】:

您可以查询PROCESSOR_ARCHITECTURE。描述了here,您必须添加一些额外的检查,因为对于任何 32 位进程,PROCESSOR_ARCHITECTURE 的值将是 x86,即使它在 64 位操作系统上运行。在这种情况下,变量PROCESSOR_ARCHITEW6432 将包含操作系统位数。更多详情见MSDN

Dim WshShell
Dim WshProcEnv
Dim system_architecture
Dim process_architecture

Set WshShell =  CreateObject("WScript.Shell")
Set WshProcEnv = WshShell.Environment("Process")

process_architecture= WshProcEnv("PROCESSOR_ARCHITECTURE") 

If process_architecture = "x86" Then    
    system_architecture= WshProcEnv("PROCESSOR_ARCHITEW6432")

    If system_architecture = ""  Then    
        system_architecture = "x86"
    End if    
Else    
    system_architecture = process_architecture    
End If

WScript.Echo "Running as a " & process_architecture & " process on a " _ 
    & system_architecture & " system."

【讨论】:

  • 我必须为此添加一个非常重要的注释...如果您运行 32 位 CMD shell 并在该 shell 中运行 64 位 wscript/cscript 可执行文件,请检查您的代码正确返回x86。但是,如果您要在代码中加载 COM DLL 或类似内容,主机会像加载 64 位 DLL 一样加载它们。在我手动测试该命令并且它起作用之前,我花了四个小时猛烈抨击它,我知道有些不对劲。
【解决方案3】:

这是基于@Bruno 非常简洁的答案的一对 VBScript 函数:

Function Is32BitOS()
    If GetObject("winmgmts:root\cimv2:Win32_Processor='cpu0'").AddressWidth _
       = 32 Then
        Is32BitOS = True
    Else
        Is32BitOS = False
    End If
End Function

Function Is64BitOS()
    If GetObject("winmgmts:root\cimv2:Win32_Processor='cpu0'").AddressWidth _
       = 64 Then
        Is64BitOS = True
    Else
        Is64BitOS = False
    End If
End Function

更新:根据@Ekkehard.Horner 的建议,这两个函数可以更简洁地编写using single-line syntax 如下:

Function Is32BitOS() : Is32BitOS = (GetObject("winmgmts:root\cimv2:Win32_Processor='cpu0'").AddressWidth = 32) : End Function

Function Is64BitOS() : Is64BitOS = (GetObject("winmgmts:root\cimv2:Win32_Processor='cpu0'").AddressWidth = 64) : End Function

(请注意,GetObject(...) = 32 条件周围的括号不是必需的,但我相信它们增加了关于运算符优先级的清晰度。还请注意,在修改后的实现中使用的单行语法避免使用If/Then 构造!)

更新 2:根据@Ekkehard.Horner 的额外反馈,有些人可能会发现这些进一步修订的实现既简洁又增强了可读性:

Function Is32BitOS()
    Const Path = "winmgmts:root\cimv2:Win32_Processor='cpu0'"
    Is32BitOS = (GetObject(Path).AddressWidth = 32)
End Function

Function Is64BitOS()
    Const Path = "winmgmts:root\cimv2:Win32_Processor='cpu0'"
    Is64BitOS = (GetObject(Path).AddressWidth = 64)
End Function

【讨论】:

  • 按 LOC 或小时支付的人会这样;所有其他人都会将“Function F() : If Condition Then F = True Else F = False : End Function”识别为肥胖。
  • 精益版应该是:“Function F() : F = Condition : End Function”——没有三元运算符,没有考虑是否切换赋值,少了4行。
  • 一个条件表达式(例如“GetObject(...).AdressWidth = 64”计算为一个布尔值,可以毫不费力地分配给函数名(VBScript从函数返回某些内容的方式) )。
  • +1 用于精益版本(如果您使用 3 行代码,它同样精益;重点是将条件表达式(的结果)直接分配给函数名称)。
【解决方案4】:

WMIC 查询可能很慢。使用环境字符串:

Function GetOsBits()
   Set shell = CreateObject("WScript.Shell")
   If shell.ExpandEnvironmentStrings("%PROCESSOR_ARCHITECTURE%") = "AMD64" Then
      GetOsBits = 64
   Else
      GetOsBits = 32
   End If
End Function

【讨论】:

    【解决方案5】:

    确定 CPU 是 32 位还是 64 位很容易,但问题是如何确定操作系统是 32 位还是 64 位。当 64 位 Windows 运行时,ProgramW6432 环境变量被定义。

    这个:

    CreateObject("WScript.Shell").Environment("PROCESS")("ProgramW6432") = ""
    

    对于 32 位操作系统将返回 true,对于 64 位操作系统返回 false,并且适用于所有版本的 Windows,包括非常旧的版本。

    【讨论】:

    • 所以如果你自己运行 vbs,它会默认使用 32 位脚本,所以你必须使用 C:\Windows\Syswow64\cscript 来运行它,然后它会返回 64 位跨度>
    • 你带来了一个好点。老实说,我使用了这种技术,它在 Windows 2000、XP 32 位、Windows 7、8 和 10 上运行良好,但我还没有在所有操作系统上测试过它。所以......这是一个简单的解决方案,可能不适用于所有版本的 Windows,如 Server 2003。
    • 我找到了一个简单的解决方案,只要看看 C:\windows\syswow64\cacript 是否存在,如果它不是 32 位的
    • @seanClt: @seanClt: %windir%\SysWow64\CScript 存在...除非您在不存在 WoW64 系统的 x64 Windows 的剥离版本上运行:如 Windows PE,删除 WoW64-Support 时的服务器核心等。
    【解决方案6】:

    布鲁诺回答的附录:您可能想要检查操作系统而不是处理器本身,因为您可以在较新的 CPU 上安装较旧的操作系统:

    strOSArch = GetObject("winmgmts:root\cimv2:Win32_OperatingSystem=@").OSArchitecture
    

    返回字符串“32 位”或“64 位”。

    【讨论】:

    • 附录到附录:.OSArchitecture 在 XP 上不存在。
    • 它可以返回“64 位”,也可能是“64 位”,具体取决于本地化。
    【解决方案7】:

    您还可以检查文件夹C:\Windows\sysnative 是否存在。此文件夹(或更好的别名)仅存在于 32 位进程中,请参阅File System Redirector

    Set fso = CreateObject("Scripting.FileSystemObject")
    Set wshShell = CreateObject( "WScript.Shell" )
    
    If fso.FolderExists(wshShell.ExpandEnvironmentStrings("%windir%") & "\sysnative" ) Then
        WScript.Echo "You are running in 32-Bit Mode"
    Else
        WScript.Echo "You are running in 64-Bit Mode"
    End if
    

    注意:此脚本显示您当前的进程是在 32 位还是 64 位模式下运行 - 它不显示您的 Windows 架构。

    【讨论】:

    • sysnative 在未更新的 64 位 XP/2003 中不存在。
    • XP/2003 几岁了? 20 年?
    【解决方案8】:
    ' performance should be good enough
    ' Example usage for console:
    ' CSript //NoLogo *ScriptName*.vbs
    ' If ErrorLevel 1 Echo.Win32
    ' VBScript:
    On Error Resume Next
    Const TargetWidth = 32
    Set WMI = GetObject("winMgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
    Set Query = WMI.ExecQuery("SELECT AddressWidth FROM Win32_Processor")
    For Each Item in Query
      If Item.AddressWidth = TargetWidth Then
        WScript.Quit 1
      End If
    Next
    WScript.Quit 0
    

    【讨论】:

    • 虽然此代码 sn-p 可能是解决方案,但 including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
    【解决方案9】:

    使用环境。在XP中测试过,但是我找不到32位的CPU来测试...

       function getbitsos()
          with WScript.CreateObject("WScript.Shell").environment("PROCESS")
            if .item("PROCESSOR_ARCHITECTURE") ="X86" and .item("PROCESSOR_ARCHITEW6432") =vbnullstring Then
              getbitsos=array(32,32,32)
            elseif .item("PROGRAMFILES(x86)")=vbnullstring Then 
              getbitsos=array(64,32,32)
            elseif .item("PROGRAMFILES(x86)")=.item("PROGRAMFILES") Then
              getbitsos=array(64,64,32)
            Else
              getbitsos=array(64,64,64)
            end if   
          end with
        end function
        
        a=getbitsos()
        wscript.echo "Processor " &a(0) & vbcrlf & "OS "  & a(1) &vbcrlf& "Process " & a(2)& vbcrlf 
    

    【讨论】:

      猜你喜欢
      • 2012-03-02
      • 2016-02-07
      • 2018-01-18
      • 1970-01-01
      • 2011-02-21
      • 2010-10-23
      • 1970-01-01
      • 2010-11-18
      相关资源
      最近更新 更多