我正在运行一个可以在 x64 Windows 下运行的 VBScript。我需要从注册表的 32 位部分读取注册表项。为此,我使用 pathHKLM\Software\Wow6432Node\xyz
而不是HKLM\Software\xyz
. 如何检查脚本是否在 x64 下执行?
6 回答
即使在 64 位版本的 Windows 上,您的脚本也可以在 32 位模式下执行。
您可以使用以下代码来确定实位模式,您的脚本运行在:
option explicit
function Determine64BitMode
dim Shell, Is64BitOs
set Shell = CreateObject("WScript.Shell")
on error resume next
Shell.RegRead "HKLM\Software\Microsoft\Windows\CurrentVersion\ProgramFilesDir (x86)"
Is64BitOs = Err.Number = 0
on error goto 0
if Is64BitOs then
Determine64BitMode = InStr(Shell.RegRead("HKLM\Software\Microsoft\Windows\CurrentVersion\ProgramFilesDir"), "(x86)") = 0
else
Determine64BitMode = false
end if
end function
dim ExecutingIn64BitMode
ExecutingIn64BitMode = Determine64BitMode
if ExecutingIn64BitMode then
MsgBox "64 bit"
else
MsgBox "32 bit"
end if
我不确定您是否需要检查脚本是否在 x64 下执行。
尝试从 读取HKLM\Software\Wow6432Node\xyz
,如果失败,请尝试从 读取HKLM\Software\xyz
,如果失败,您的注册表项不存在,请采取任何适当的操作。
当然,如果您的设计更复杂(例如,如果该注册表项不存在,则将值写入该注册表项),那么该建议将不起作用。
这是用于检查操作系统的 VBScript。您可能还需要解释Win32_OperatingSystem 类中可用的属性
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery _
("Select * from Win32_OperatingSystem")
For Each objOperatingSystem in colOperatingSystems
msg = objOperatingSystem.Caption & " " & _
objOperatingSystem.Version & " " & _
objOperatingSystem.OSArchitecture
msgbox msg
Next
请注意,对于 Windows XP 和 2003,OSArchitecture
不可用,在这种情况下,您可能必须检查Caption
或Version
确定您的操作系统是否为 64 位。
您也可以根据所需的复杂程度使用类似的东西。
这是基于 Microsoft 知识库文章How To Check If Computer Is Running A 32 Bit or 64 Bit Operating System的解决方案:
Function Is64BitOS()
Is64BitOS = Not(Is32BitOS())
End Function
Function Is32BitOS()
Const sRegKey = "HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0"
Const sIdentifierValue = "Identifier"
Const sPlatformIDValue = "Platform ID"
Dim oSh : Set oSh = CreateObject("WScript.Shell")
Dim sIdentifier, nPlatformID
sIdentifier = oSh.RegRead(sRegKey & "\" & sIdentifierValue)
nPlatformID = oSh.RegRead(sRegKey & "\" & sPlatformIDValue)
Set oSh = Nothing
If InStr(sIdentifier, "x86") > 0 And nPlatformID = 32 Then
Is32BitOS = True
Else
Is32BitOS = False
End if
End Function
替代解决方案
可以在此处找到使用WMI的替代且更简洁的解决方案。
您没有提到您使用什么 API 从注册表中读取。例如,如果您使用 WMIStdRegProv
类,则可以使用该__ProviderArchitecture
标志来请求访问 32 位注册表配置单元,而不管脚本是在 32 位还是 64 位 Windows 脚本主机下运行。此技术在 MSDN 中的在 64 位平台上请求 WMI 数据一文中进行了描述。
这是从 32 位注册表读取的示例:
strComputer = "."
Const HKLM = &h80000002
''# Specify the required registry bitness
Set oCtx = CreateObject("WbemScripting.SWbemNamedValueSet")
oCtx.Add "__ProviderArchitecture", 32
oCtx.Add "__RequiredArchitecture", True
''# Load the 32-bit registry provider
Set oLocator = CreateObject("WbemScripting.SWbemLocator")
Set oWMI = oLocator.ConnectServer(strComputer, "root\default",,,,,, oCtx)
Set oReg = oWMI.Get("StdRegProv")
''# Specify input parameters for the GetStringValue method call
Set oInParams = oReg.Methods_("GetStringValue").InParameters
oInParams.hDefKey = HKLM
oInParams.sSubKeyName = "Software\xyz"
oInParams.sValueName = "foobar"
''# Read a string value from the registry
Set oOutParams = oReg.ExecMethod_("GetStringValue", oInParams,, oCtx)
WScript.Echo oOutParams.sValue
另请注意,在这种情况下,应以通常的方式指定 32 位密钥名称,HKLM\Software\xyz
而不是HKLM\Software\Wow6432Node\xyz
.
这显示了系统和进程架构:
Option Explicit
Dim WshShell, WshEnv
Set WshShell = WScript.CreateObject("WScript.Shell")
Set WshEnv = WshShell.Environment("System")
MsgBox "System: " & WshEnv("PROCESSOR_ARCHITECTURE")
Set WshEnv = WshShell.Environment("Process")
MsgBox "Process: " & WshEnv("PROCESSOR_ARCHITECTURE")
只需检查您需要的那个<> "x86"
。
一个非常简单的解决方案是检查(虚拟)文件夹是否C:\Windows\sysnative
存在。此文件夹仅存在于 32 位进程中,请参阅文件系统重定向器
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
请注意,仅适用于 Windows Server 2003 和 Windows XP 或更高版本。