Learn about Windows PowerShell
Hey, Scripting Guy! I know that when I run a script I can use code to determine whether the script is running under WScript or CScript. What I can’t figure out is this: how can I determine the default script host on a computer before I run a script?-- AT
Hey, AT. You know, it’s not very often that people completely stump the Scripting Guys; however, we have to admit this question posed a bit of a challenge. (OK, OK: so maybe it’s not that hard to stump the Scripting Guys; to be honest, it’s actually pretty easy. But you guys don’t need to know that.) We had no idea how to answer this question, and we knew it was going to take a lot of hard work and dedication in order to help you out with this.
But, in the face of adversity, did the Scripting Guys give up? Well, as a matter of fact we did. However, in the process of doing something totally unrelated, we accidentally stumbled upon the answer. Here, using a somewhat-roundabout methodology, is a script that will tell you the default script host on a computer:
Const HKEY_CLASSES_ROOT = &H80000000
strComputer = "."
Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
strKeyPath = "VBSFile\Shell\Open\Command"
strValue = LCase(strValue)
If InStr(strValue, "wscript.exe") then
As it turns out, information about the default script host is stored in the registry, although not in a particularly obvious location. What you need to do is open HKEY_CLASSES_ROOT, find the registry key VBSFile\Shell\Open\Command and then look at the default value. (The default value is an otherwise-unnamed registry value, one that shows up as (Default) in Regedit.) The value of (Default) will be the path to the script host executable (e.g., %SystemRoot%\System32\WScript.exe). In turn, the executable file tells you whether the default script host is CScript or WScript.
So how do we actually get to that value? Well, we begin by defining a constant named HKEY_CLASSES_ROOT and setting the value to &H80000000; that tells the script which registry hive we want to work with. We then connect to the WMI service on the local computer (although we could just as easily run this script against a remote machine), taking care to bind to the root\default namespace. (Most WMI scripts use the root\cimv2 namespace, but, for some reason, the System Registry Provider lives in root\default instead. Probably cheaper housing or better schools.)
After making the connection we create a variable named strKeyPath, assigning it the value VBSFile\Shell\Open\Command. At that point we’re ready to read the value from the registry.
What’s that? Didn’t we forget something? No, we didn’t forget anything. (Although now that you mention it we’re beginning to wonder if anyone turned off the stove when we left the house this morning.) You’re right that, in most WMI registry scripts, we would need to assign values to two variables, one to represent the registry key, the other to represent the desired value within that registry key. In this case, however, we don’t need to create a variable in which to store the name of the registry value. Why not? Because, technically, (Default) values don’t actually have a name; they’re just, well, the default values. What we’ll end up doing is telling the script to read a Null value from this particular registry key. That doesn’t sound like a very good plan but, fortunately, the Registry Provider will know that this means to read the (Default) value.
In fact, as long as we’re on the subject, here’s the line of code that retrieves the value for us:
Because (Default) happens to have the REG_EXPAND_SZ data type we call the GetExpandedStringValue method, passing four parameters:
HKEY_CLASSES_ROOT, the constant that tells the script which registry hive to work with.
strKeyPath, the variable that tells the script which registry key to work with.
vbNullString, a VBScript constant representing a Null value. This is where we would usually insert a variable representing the value name but, as we noted, this time around our value doesn’t have a name.
strValue, an “out” parameter. GetExpandedStringValue needs a place to store the value it reads from the registry; an out parameter is simply a placeholder variable where that value can be stashed.
As soon as GetExpandedStringValue does its thing we use this line of code to change all the characters in strValue to lowercase; we do that to make it easier to determine whether the value contains a particular string or not:
strValue = LCase(strValue)
Finally, we call the InStr function, looking to see if the string value wscript.exe can be found anywhere within strValue. If it can, then we echo back the fact that the default script host is WScript; if it can’t, then that must mean the default script host is CScript:
If InStr(strValue, "wscript.exe") then
So there you go, AT: now you can determine the default script host on a computer without running a script. (Yes, we know, you have to run the script that determines the default script host…but you get the point.) We hope you find this useful, and we hope everyone has learned an important lesson today: try as you might, you can’t stump the Scripting Guys.
Well, not unless you ask us a question we can’t answer. But you’ll never stump us by asking a question that we can answer.
OK: almost never.
This test works no longer under WSH 5.7.
Now there are two commands for VBSFile: Open for WScript.exe and Open2 for CScript.exe and the default value of HKCR\VBSFile\Shell\ is one of them.
This seems to be a nasty breaking change because the WshShell.Run does not evaluate the default value of HKCR\VBSFile\Shell\ but instead always looks for the "Open" command which is now always WScript.exe.
This doesn't work on Windows 7, it always returns "WScript"
C:\>cscript //h:wscript //s
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.
Command line options are saved.
The default script host is now set to "wscript.exe".
C:>"What is my default Scripting Host.vbs"
C:>cscript //h:cscript //s
The default script host is now set to "cscript.exe".
Content of my vbs file is a copy & paste of your script above.
On Windows 7, as pointed out before, there are 2 'open' command listed under HKEY_CLASSES_ROOT\VBSFile\Shell.
'Open\Command' calls WScript.exe, 'Open2\Command' calls CScript.
As to which is the default script host, that's determined by the default value in the key HKEY_CLASSES_ROOT\VBSFile\Shell key.
Mine says Open2, ergo it uses CScript.