How to pass a command with spaces and quotes as a single parameter to CScript?
Asked Answered
G

2

5

I'm using CScript to run a VBScript file, and I need to pass a command line to the script where the parameter includes both spaces and quotes. The entire command needs to be passed as one parameter to the script. For example:

C:\> CScript myscript.vbs //Nologo "cmd.exe /c "dir && del /q *.txt""

Note the specific command line above is just an example, but it does touch on what I'm trying to do (i.e. pass a command line that involves running cmd.exe). I'm trying to solve for the general case, however.

The issue is that CScript appears to be getting confused trying to determine where quotes are opening and closing. At least sometimes.

The following script may help explain. It just outputs the passed in arguments as it sees them:

Dim count
For count = 0 To WScript.Arguments.Count-1
    WScript.Echo CStr(count) & " = " & WScript.Arguments.Item(count)
Next

Often times, it works as expected:

C:\> cscript myscript.vbs //Nologo "1 2 3"
0 = 1 2 3

But when there are quotes inside the quoted parameter, things change:

C:\> cscript myscript.vbs //Nologo "1 "2 3""
0 = 1 2
1 = 3

I understand there is an introduced ambiguity about whether each quote is opening or closing a parameter in the above example, so next I tried escaping the internal quotes so the command processor will treat them as literal strings:

C:\> cscript myscript.vbs //Nologo "1 ^"2 3^""
0 = 1 ^2
1 = 3

Hmmm, looks like that only works when the shell does your globbing and such for you. I doubt cscript understands ^ as an escape character like cmd.exe does.

Using single quotes inside the double-quoted command (e.g. "cmd.exe /c 'dir && cd \'") properly parses as a single parameter but won't work because for the case of invoking cmd.exe with the /c parameter, single quotes are not sufficient. For example:

C:\> cmd /c 'dir && cd \'
''dir' is not recognized as an internal or external command,
operable program or batch file.

I suppose I could just iterate over all the arguments in the script and join them back to one long string, but I'll lose the internal quotes and context that they provide doing that. Or maybe I do use single quotes inside the the double-quoted param and map those back to double quotes inside the script. But what if the intention was single quotes for some future case I'm not considering? Since I'm attempting to solve for the general case, I can't make that determination.

Any ideas?

Gnomon answered 10/4, 2012 at 15:30 Comment(2)
Take a look at this SO question: Double quotes in VBScript argument. Maybe some helpfull answers there.Dupont
Thanks. I will take a look. Getting the command line from WMI may just work.Gnomon
K
4

It appears like you are trying to delineate values in your parameters. I suggest using something besides quotes and adding back the quotes. For example using tildes:

Dim count
For count = 0 To WScript.Arguments.Count-1
    WScript.Echo CStr(count) & " = " & replace(WScript.Arguments.Item(count),"~",chr(34))
Next

Passing:

cscript myscript.vbs //Nologo "1 ~2 3~"
0 = 1 "2 3"
Kriss answered 10/4, 2012 at 15:41 Comment(1)
I ended up going with a solution like this.Gnomon
S
0

You have two options.

The first is easy enough--escape the quotes using the carat (^).

C:\> CScript myscript.vbs //Nologo "cmd.exe /c ^"dir && del /q *.txt^""

The second option is to use a different delimiter. In a command like this, the shell uses a space as a delimeter between parameters. But the shell allows others like semicolons, commas, equal signs, and tabs. By implementing one of these, you wouldn't need to surround parameters with quotes because spaces would no longer break your command line.

Shot answered 10/4, 2012 at 23:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.