On 64-bit Windows systems, it is possible for a VBScript to run in either 32-bit or 64-bit mode. If a script is running in 32-bit mode, for example, and needs to run in64-bit, it’s important to be able to detect the discrepancy and correct it.
Below is code to functions and subroutines which can help ensure that a script is running in the right environment. The functions include:
- RunInMode(): When supplied with the value "any", this function will ignore the environment in which it’s running. When supplied with the value "x86", it will force the script to run in a 32-bit Cscript environment on x64 systems. When supplied with the value "x64" it will force the script to run in 64-bit mode on 64-bit systems and terminate if run on an x86 system. The value "native" will run the script in 32-bit mode on a 32-bit OS and 64-bit mode on a 64-bit OS.
- GetShellEnv(): When the script is run in a 32-bit Cscript environment, this function returns "x86". When run in a 64-bit environment, it returns "x64". A script running in 32-bit mode on a 64-bit system will return "x86".
- RestartWithCscript64(): When executed, this function will restart the script with the 64-bit version of Cscript.
- RestartWithCscript32(): When executed, this function will restart the script with the 32-bit version of Cscript (whether on a 32-bit or 64-bit OS).
Although all four functions work together (and therefore should be included in any script you want to use them in), the only that typically needs to be accessed directly is RunInMode.
For instance, if the first line in a script is:
RunInMode("x86")
The code will restart the script in 32-bit mode if it’s running in 64-bit mode. The RunInMode function will use the other three functions as needed to run the script in the correct mode. It’s unnecessary to call the other functions unless the script has a need to do so.
Dim RC
WScript.Echo "Script starts."
RunInMode "x86"
WScript.Echo "Now running in mode: " & getShellEnv‘
‘ Run with 32-bit Cscript on 64-bit OS
‘
Public Function RestartWithCScript32()
Dim theShell, theFso
Set theShell = CreateObject("Wscript.shell")
Set theFso = CreateObject("Scripting.FileSystemObject")Dim strCMD, iCount
strCMD = theShell.ExpandEnvironmentStrings("%SYSTEMROOT%") & "\SysWOW64\cscript.exe"
If NOT theFso.FileExists(strCMD) Then strCMD = "cscript.exe"
strCMD = strCMD & " " & Chr(34) & Wscript.ScriptFullName & Chr(34)
If Wscript.Arguments.Count > 0 Then
For iCount = 0 To WScript.Arguments.Count – 1
if Instr(Wscript.Arguments(iCount), " ") = 0 Then
strCMD = strCMD & " " & Wscript.Arguments(iCount) & " "
Else
If Instr("/-\", Left(Wscript.Arguments(iCount), 1)) > 0 Then
If InStr(WScript.Arguments(iCount),"=") > 0 Then
strCMD = strCMD & " " & Left(Wscript.Arguments(iCount), _
Instr(Wscript.Arguments(iCount), "=") ) & """" & _
Mid(Wscript.Arguments(iCount), _
Instr(Wscript.Arguments(iCount), "=") + 1) & """ "
ElseIf Instr(WScript.Arguments(iCount),":") > 0 Then
strCMD = strCMD & " " & Left(Wscript.Arguments(iCount), _
Instr(Wscript.Arguments(iCount), ":") ) & """" & _
Mid(Wscript.Arguments(iCount), _
Instr(Wscript.Arguments(iCount), ":") + 1) & """ "
Else
strCMD = strCMD & " """ & Wscript.Arguments(iCount) & """ "
End If
Else
strCMD = strCMD & " """ & Wscript.Arguments(iCount) & """ "
End If
End If
Next
End If
WScript.Echo strCMD
theShell.Run strCMD, 0, FalseSet theShell = Nothing
Set thefso = nothing
End Function‘
‘ Run with 64-bit Cscript on 64-bit OS
‘
Public Function RestartWithCScript64()
Dim theShell, theFso
Set theShell = CreateObject("Wscript.shell")
Set theFso = CreateObject("Scripting.FileSystemObject")Dim strCMD, iCount
strCMD = theShell.ExpandEnvironmentStrings("%SYSTEMROOT%") & "\sysnative\cscript.exe"
If NOT theFso.FileExists(strCMD) Then strCMD = "cscript.exe"
strCMD = strCMD & " " & Chr(34) & Wscript.ScriptFullName & Chr(34)
If Wscript.Arguments.Count > 0 Then
For iCount = 0 To WScript.Arguments.Count – 1
if Instr(Wscript.Arguments(iCount), " ") = 0 Then
strCMD = strCMD & " " & Wscript.Arguments(iCount) & " "
Else
If Instr("/-\", Left(Wscript.Arguments(iCount), 1)) > 0 Then
If InStr(WScript.Arguments(iCount),"=") > 0 Then
strCMD = strCMD & " " & Left(Wscript.Arguments(iCount), _
Instr(Wscript.Arguments(iCount), "=") ) & """" & _
Mid(Wscript.Arguments(iCount), _
Instr(Wscript.Arguments(iCount), "=") + 1) & """ "
ElseIf Instr(WScript.Arguments(iCount),":") > 0 Then
strCMD = strCMD & " " & Left(Wscript.Arguments(iCount), _
Instr(Wscript.Arguments(iCount), ":") ) & """" & _
Mid(Wscript.Arguments(iCount), _
Instr(Wscript.Arguments(iCount), ":") + 1) & """ "
Else
strCMD = strCMD & " """ & Wscript.Arguments(iCount) & _
""" "
End If
Else
strCMD = strCMD & " """ & Wscript.Arguments(iCount) & """ "
End If
End If
Next
End If
WScript.Echo strCMD
theShell.Run strCMD, 0, False
Set theShell = Nothing
Set thefso = NothingEnd Function
Public Function getShellEnv()
Dim shellEnv, shellType, shellValue, wshProcEnv
Set theShell = CreateObject("Wscript.Shell")
Set WshProcEnv = theshell.Environment("Process")
shellType = WshProcEnv("PROCESSOR_ARCHITECTURE")if shellType = "" then shellType = "x86"
Select Case shellType
Case "x86", "X86":
shellValue = "x86"
Case "AMD64", "x64", "X64":
shellValue = "x64"
Case Else
WScript.echo "Unknown shell environment type: " & shellType
WScript.Echo "Expected x86, x64, or AMD64."
WScript.Quit 1
End SelectgetShellEnv = shellValue
End Function
Public Sub RunInMode(runMode)If LCase(runMode)="any" Then
WScript.echo "Script can run in either 32-bit or 64-bit."
Exit Sub
End IfDim osType, shellType
shellType = getShellEnv
osType = getOSArchitecture
WScript.echo "Desired run mode: " & runMode
WScript.Echo "Actual run mode: " & shellType
If runMode = "native" And osType = "x64" And shellType<>"x64" Then
WScript.echo "Requested 64-bit when OS is 64-bit. Currently running in 32-bit."
WScript.Echo "Restarting script in 64-bit mode."
RC = RestartWithCScript64
WScript.Quit RC
End IfIf runMode = "x64" And osType <> "x64" Then
WScript.echo "Requested 64-bit mode on a 32-bit OS. Aborting."
WScript.Quit 1
End If
If runMode = "x64" And shellType = "x86" Then
WScript.Echo "Requested 64-bit mode but running in 32-bit. Restarting."
RC = RestartWithCScript64
WScript.Quit RC
End If
If runMode = "x86" And shellType = "x64" Then
WScript.Echo "Requested 32-bit mode but running as 64-bit. Restarting."
RC = RestartWithCScript32
WScript.Quit RC
End If
End Sub