Hey, Scripting Guy! I’m trying to create a process that runs a script under the CScript script host. However, I keep running into problems because there are spaces in the script path name. How can I use WMI’s Win32_Process class to run a script under CScript when there are spaces in the script path name?
— TA
Hey, TA. ZDjhdvS ASBF VX
Oh. Sorry; it’s hard to get used to typing while wearing this heavy coat and these ski gloves. But we’re going to have to get used to it: like it or not, winter is upon us. Granted, it’s not even November yet, but this morning the Scripting Guy who writes this column had to use an ice scraper to scrape the frost off his car windows. That’s a bad sign; after all, he rarely has to scrape frost off his car windows when the temperature is in the 80s. As it was, as he headed off to work the temperature outside was just 35 degrees Fahrenheit. That’s also a bad sign: when you’re dealing with Fahrenheit you never want to see a temperature that starts with a 3.
Ever.
So, anyway asdjSdjkSY ABNS ASDNB SA DDDPPpppS
Sorry. So, anyway, the Scripting Guy who writes this column is bundled up and in a bad mood; after all, this past year the Seattle area had a so-so Spring, a miserable Summer, and a Fall that lasted about 3 days, total. And now we’re right back into winter which, last year, meant windstorms, ice storms, power failures, and all those other winter pastimes that never make it onto calendars or greeting cards.
Gee, and we were afraid that winter would never get here.
As you probably know, neither snow nor rain not heat nor gloom of night can keep the US postal service from the swift completion of its appointed rounds. So does that mean that the Scripting Guys won’t be deterred by a little cold weather? Heck no; in fact, the Scripting Guy who writes this column had every intention of going back home, crawling under the covers, and staying there till Spring. And he probably would have, too, except for his unwavering devotion to duty and to his readers.
Plus the fact that the Scripting Son starts college next year, which means this is not a good time for the Scripting Dad to be quitting his job.
With that in mind, TA, here’s a script that can start a second script using the Win32_Process class, even if the path name to that second script includes blank spaces:
strComputer = “.”Set objProcess = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2:Win32_Process”)
strCommand = “cscript ” & Chr(34) & “C:\Documents and Settings\Scripts\QA.vbs” & Chr(34) objProcess.Create strCommand,null,null,intProcessID
As you can see (assuming that you, unlike those of us in the Seattle area, don’t have to scrape the ice off your monitor) we start off by connecting to the WMI service on the local computer. Actually, to be a little more technical – and a little more accurate – we connect to the WMI class Win32_Process on the local computer; note that we specified Win32_Process in our WMI path:
\root\cimv2:Win32_Process
Why did we do that? Because the Create method (the method used create a new process) is a so-called “static” method; any time you use a static method you need to bind to the WMI class rather than the individual instances of the class. You might have noticed that we don’t have an ExecQuery method that selects instances of the Win32_Process class. That’s why: we don’t want instances of the Win32_Process class.
And yes, you can run this script against a remote computer; to do that, simply assign the name of the remote computer to the variable strComputer:
strComputer = “atl-ws-01”
Keep in mind, however, that the script will run in an invisible window on that remote machine; nothing will ever appear onscreen. That’s probably why TA is explicitly running the script under CScript: by doing so, if the script includes any Echo commands, those commands will be written to the invisible console window and will not pop up as message boxes. And that’s good; after all, those message boxes will also be invisible. If an invisible message box did pop up while your script was running, the script would pause until someone dismissed that message box. Needless to say, invisible message boxes are a bit difficult to dismiss.
Note. Actually, they’re impossible to dismiss. The only way to get rid of them would be to terminate the script process, which would also terminate the script. If you’re going to use code like this to start a script on a remote machine make sure that you always run that script under CScript. |
As it turns out, TA has been having trouble with this line of code:
objWMIService.Create(“Cscript C:\Documents and Settings\Scripts\QA.vbs”,null,null,intProcessID)
TA also correctly identified the problem: it’s the blank spaces that appear in the path name. When you call the Create method, you need to enter a command that looks exactly like the command you would type from the command prompt. How would you enter this command from the command prompt? Well, because of the blank spaces, you’d enclose the file path in double quote marks, like so:
Cscript “C:\Documents and Settings\Scripts\QA.vbs”
But we can’t do that here. If we enclose the command in double quotes we’ll have double quotes inside of double quotes, and all … heck … will break loose:
objWMIService.Create “Cscript “C:\Documents and Settings\Scripts\QA.vbs””,null,null,intProcessID
So how are we going to deal with the issue of double double quotes in our Create command? We’re not; instead, we’re going to use this little trick to bypass the double quote problem altogether:
strCommand = “cscript ” & Chr(34) & “C:\Documents and Settings\Scripts\QA.vbs” & Chr(34)
What we’re doing here is simply constructing a string value equivalent to the command we would type at the command prompt; we do that by combining the following values:
• |
Cscript (Note the blank space immediately following the letter t.) |
• |
Chr(34). What’s Chr(34)? Well, the Chr function takes an ASCII value and converts it to a character. Guess which character the ASCII value 34 converts into? That’s right: the double quote mark. |
• |
C:\Documents and Settings\Scripts\QA.vbs |
• |
Chr(34) |
Or, a little more visually:
Cscript + ” + C:\Documents and Settings\Scripts\QA.vbs + ” _____________________________________________________Cscript “C:\Documents and Settings\Scripts\QA.vbs”
Now we don’t have to worry about double double quotes; all our double quotes are safely tucked away inside the variable strCommand. In turn, that means we can create a new process – and run the script – simply by using strCommand as the first parameter passed to the Create method:
objProcess.Create strCommand,null,null,intProcessID
And that should do it
Incidentally, would you like to know how cold it really got here in Seattle? Well, it was so cold that the Scripting Guy who writes this column actually had his brain freeze. When this Scripting Guy sat down to tackle this question, he copied TA’s original script, saving it to a file named C:\Scripts\Test Scripts\Test.vbs. Of course, that meant he also had to change path to the script being called by Test.vbs as well. So what did he change that to? Sadly, you’re right: he changed the path to C:\Scripts\Test Scripts\Test.vbs. That meant he had a script – Test.vbs – that had only one mission in life: to open and run a script called Test.vbs.
Was that a problem? Well, only if you think that having hundreds of command windows suddenly pop up on your screen is a problem. When he started Test.vbs it immediately, and dutifully, started a second copy of Test.vbs. That second copy promptly started a third copy of Test.vbs, which promptly started a fourth copy of Test.vbs, which – well, you get the idea. All these command windows were popping up so quickly that he couldn’t deal with them; he couldn’t even stop the process because each Cscript.exe process would pop up and then disappear before he could kill it; meanwhile, 5 or 6 more processes would pop up along the way. And because the processes were created faster than they could be terminated, his screen was soon littered with empty command windows.
In fact, he couldn’t even shut down any of the other applications he was running because each time he clicked somewhere (anywhere) a new command window would pop up and steal the focus away. All he could do was shut down the computer.
Trust us: it was way worse than it sounds. And it doesn’t really sound all that good, to begin with.
And then – alas – he did the exact same thing all over again! After glancing at the code, the Scripting Guy who writes this column assumed that he’d been the victim of an unfortunate computer glitch; after all, Test.vbs didn’t include For Next loops or Do While loops or anything else that might cause multiple command windows to appear on screen. And so he ran the script again. It was only while watching the command windows re-proliferate that he realized what he had done. (And, after restarting the computer again, finally managed to fix it.)
But don’t worry: as soon as spring comes and his brain unfreezes everything should be fine.
0 comments