Hey, Scripting Guy! How can I get the command window to stay open when I right-click a .VBS file and choose Open With Command Prompt??
Hey, BB. You know, according to BB’s email signature, he’s 9 years old. If that’s true, well, that’s absolutely amazing. A 9-year-old who knows VBScript? At age 9 the Scripting Guys could barely feed themselves or tie their own shoes.
Which, in their case, simply means that the more things change the more they stay the same.
Of course, we have to admit that, just because BB says he’s 9 years old doesn’t mean he really is 9 years old. After all, the Scripting Editor continues to insist that she’s 23 years old. But how, then, can she explain the photographs that clearly show her attending Franklin Delano Roosevelt’s Inauguration Ball in 1937? The truth is, she can’t.
Instead, she just throws things any time the subject is broached.
Anyway, we can’t be sure that BB really is 9 years old, but we’ll try to figure out a way to verify that, maybe by asking him a question that only a 9-year-old would know the answer to. You know, like this one: name all four Ninja Turtles.
Good point; after all, even the Scripting Guy who writes this column knows the answer to that: Leonardo, Donatello, Michelangelo, and Raphael. And that’s without using the Internet to look up the answer.
Note. Actually, the Scripting Guy who writes this column never uses the Internet, or anything else, to look up an answer. He just assumes he knows everything.
Of course, whether BB is really 9 years old or not doesn’t matter; either way he has a good question here. If you right-click a .VBS file one of the options available to you on the context menu is this: Open With Command Prompt. If you choose that option something seems to happen: typically a command window will briefly flash onscreen and then just as quickly disappear. And that’s it. Why doesn’t the script actually run, and why doesn’t the command window stay open?
Let’s take the first question first. (Kind of an unusual approach for Hey, Scripting Guy!, isn’t it?) As it turns out, the script actually does run; it’s just that many VBScripts execute so quickly that you don’t realize that anything happened. (About the same time the command window appears onscreen the script has completed its tasks and it’s now time for the command window to close.) Here’s one way to verify this. Create a simple script that does nothing more than display a message box:
Now, right-click this .VBS file and choose Open With Command Prompt. You should see the message box, indicating that the script really did run after all.
So then why didn’t the command window stay open? That’s easy: by default the command window tends to do its thing and then disappear. For example, open the Run dialog box, type ipconfig, and then press ENTER. You’ll see a command window open and – if you’ve got good eyesight – you might even see that Ipconfig.exe has run. But the very instant that Ipconfig finishes, the command window automatically closes. That’s why you’re usually instructed to first open a command window and then run a script or command-line tool. If you don’t the script or tool will run, but you’ll probably never see the output.
Is that a problem, having to open a command window and then run the script from within that window? Of course it is; after all, that pretty much defeats the whole idea of having an Open With Command Prompt shortcut in the first place.
But we have a good news for you, BB: if you don’t like the way the Open With Command Prompt shortcut works then you can go ahead and change the behavior of this shortcut. How do you do that? Good question; might we suggest using a script like this one:
Const HKEY_CLASSES_ROOT = &H80000000
strComputer = "."
Set objRegistry=GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
strKeyPath = "VBSFile\Shell\Open2\Command"
strValueName = ""
strValue = "cmd.exe /K cscript.exe " & Chr(34) & "%1" & Chr(34) & " %*"
As it turns out, the behavior of the Open With Command Prompt shortcut is dictated by a setting in the registry (HKEY_CLASSES_ROOT\VBSFile\Shell\Open2\Command). By default, this setting simply calls the CScript or WScript script engine (depending on your preferred settings), passing along the file path as a command-line argument:
%SystemRoot%\System32\CScript.exe "%1" %*
If we want the command window to stay open any time we run a script using this shortcut all we have to do is modify the registry setting. How do we do that? We were just about to get to that.
If you take a look at our script you’ll see that we start things off by defining a constant named HKEY_CLASSES_ROOT and setting the value to &H80000000; we’ll use this constant to tell the script which registry hive we want to work with. We then connect to the WMI service on the local computer, binding to the StdRegProv class. (Which, we should point out, resides in the root\default namespace.)
Note. Can you run this script against remote computers? Of course you can; all you have to do is assign the name of the remote computer to the variable strComputer.
After connecting to the WMI service we then assign values to three variables:
strKeyPath, which represents the registry path within the HKEY_CLASSES_ROOT hive. In this case we set the path to VBSFile\Shell\Open2\Command.
strValueName, which represents the actual registry value we want to modify. As it turns out, we want to modify the default value, a value that shows up in Regedit like this: (Default). How do we indicate that we want to work with this default value? That’s easy: we just assign an empty string (“”) to strValueName.
strValue, which represents the new value to be written to the registry.
Let’s talk a little bit about strValue. As we noted earlier, the command window tends to open up, do its thing, and then close. However, there is a way to keep the command window open after it completes its appointed tasks: you just have to use the /K (keep) switch when opening the window. And that’s exactly what we’re doing here. Notice that, this time, we aren’t directly starting Cscript.exe. Instead, we’re opening up a command window (Cmd.exe) and using the /K switch to ensure that the window stays open. That’s what this portion of our code is for:
We then pass the name of the script host (CScript.exe) and the file path as additional command-line arguments for Cmd.exe. In other words, any time someone selects Open With Command Prompt we’re going to open a persistent version of the command window, then tell the command window that – when it opens – it needs to run CScript.exe and the selected .VBS file.
Confusing? Yes, it is, at least a little. And the syntax of our command – which includes the function Chr(34), something we use to insert double quote marks into the string value – doesn’t help much. The long and short of it, however, is that strValue ends up being assigned this value:
cmd.exe /K cscript.exe "%1" %*
And, believe it or not, that’s the command that will “fix” the Open With Command Prompt shortcut.
In fact, after assigning values to our variables all we have to do is call the SetExpandedStringValue method (because our registry value happens to have the REG_EXPAND_SZ data type) and we’re done:
Now try right-clicking a .VBS file and selecting Open With Command Prompt. This time a command window should open, the script should run, and – upon completion – the command window should stay open. Pretty sweet, huh?
Again, BB, if you really are 9 years old the Scripting Guys are impressed. Or at least the Scripting Guy who writes this column is impressed. After all, was the Scripting Guy who writes this column fooling around with VBScript when he was 9? No he wasn’t, primarily because neither VBScript nor the command prompt had been invented way back then.
In fact, come to think, the number 9 hadn’t even been invented yet back when the Scripting Guy who writes this column was a kid. Wow ….