I'm running a VBScript that may run under x64 Windows. I need to read a registry key from the 32-bit part of the registry. For that I use path HKLM\Software\Wow6432Node\xyz
instead of HKLM\Software\xyz
. How can I check if the script is executed under x64?
问题:
回答1:
I'm not sure you need to check if the script is executing under x64.
Try to read from HKLM\Software\Wow6432Node\xyz
, if that fails, try to read from HKLM\Software\xyz
, if that fails, your registry key doesn't exist, take whatever action is appropriate.
Of course, if your design is more complicated (for example, you write a value into that registry key if it doesn't exist) then that suggestion won't work.
Here is a VBScript for examining the operating system. You'll probably also need explanation of the Properties available from the Win32_OperatingSystem Class
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
Note that for Windows XP and 2003, OSArchitecture
is not available, in which case you will probably have to examine either the Caption
or Version
to determine whether your OS is 64-bit.
You could also use something like this depending on the level of complexity you require.
回答2:
Even on 64-bit version of Windows you script can execute in 32-bit mode.
You can use following code to determine real bit mode, you script running on:
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
回答3:
You didn't mention what API you use to read from the registry. For example, if you use the WMI StdRegProv
class, you can use the __ProviderArchitecture
flag to request access to the 32-bit registry hive regardless of whether the script is run under 32-bit or 64-bit Windows Script Host. This technique is described in the Requesting WMI Data on a 64-bit Platform article in MSDN.
Here's an example of reading from the 32-bit registry:
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
Note also, that in this case the 32-bit key names should be specified in a usual way as HKLM\Software\xyz
instead of HKLM\Software\Wow6432Node\xyz
.
回答4:
Here is a solution based on the Microsoft knowledgebase article 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
ALTERNATIVE SOLUTION
An alternative and more concise solution that makes use of WMI can be found here.
回答5:
A very simple solution is to check whether (virtual) folder C:\Windows\sysnative
exist. This folder exists only in 32-Bit processes, see 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
Note, works only on Windows Server 2003 and Windows XP or higher.
回答6:
This shows both the system and process architectures:
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")
Just check the one you need for <> "x86"
.