Vbscript 如何将带有空格和引号的命令作为单个参数传递给CScript?

Vbscript 如何将带有空格和引号的命令作为单个参数传递给CScript?,vbscript,wsh,Vbscript,Wsh,我正在使用CScript运行VBScript文件,我需要向脚本传递一个命令行,其中参数包括空格和引号。整个命令需要作为一个参数传递给脚本。例如: C:\> CScript myscript.vbs //Nologo "cmd.exe /c "dir && del /q *.txt"" C:\> cmd /c 'dir && cd \' ''dir' is not recognized as an internal or external comman

我正在使用CScript运行VBScript文件,我需要向脚本传递一个命令行,其中参数包括空格和引号。整个命令需要作为一个参数传递给脚本。例如:

C:\> CScript myscript.vbs //Nologo "cmd.exe /c "dir && del /q *.txt""
C:\> cmd /c 'dir && cd \'
''dir' is not recognized as an internal or external command,
operable program or batch file.
请注意,上面的特定命令行只是一个示例,但它确实涉及到我正在尝试执行的操作(即传递一个涉及运行cmd.exe的命令行)。不过,我正试图解决一般情况

问题是,CScript在试图确定报价的开始和结束位置时似乎感到困惑。至少有时是这样

下面的脚本可能有助于解释。它只在看到传入的参数时输出它们:

Dim count
For count = 0 To WScript.Arguments.Count-1
    WScript.Echo CStr(count) & " = " & WScript.Arguments.Item(count)
Next
通常情况下,它会按预期工作:

C:\> cscript myscript.vbs //Nologo "1 2 3"
0 = 1 2 3
但当引用的参数中有引号时,情况会发生变化:

C:\> cscript myscript.vbs //Nologo "1 "2 3""
0 = 1 2
1 = 3
我知道在上面的示例中,每个引号是打开还是关闭一个参数会引入歧义,因此接下来我尝试转义内部引号,以便命令处理器将它们视为文本字符串:

C:\> cscript myscript.vbs //Nologo "1 ^"2 3^""
0 = 1 ^2
1 = 3
嗯,看起来只有当外壳为你做球击之类的动作时才有效。我怀疑cscript是否能像cmd.exe那样理解
^

在双引号命令(例如“cmd.exe/c'dir&&cd\”)中使用单引号可以正确地解析为单个参数,但不起作用,因为对于使用/c参数调用cmd.exe的情况,单引号是不够的。例如:

C:\> CScript myscript.vbs //Nologo "cmd.exe /c "dir && del /q *.txt""
C:\> cmd /c 'dir && cd \'
''dir' is not recognized as an internal or external command,
operable program or batch file.
我想我可以迭代脚本中的所有参数并将它们连接回一个长字符串,但这样做会丢失它们提供的内部引号和上下文。或者我确实在双引号参数中使用单引号,并将它们映射回脚本中的双引号。但是,如果我的意图是为我不考虑的未来案例提供单引号呢?因为我试图解决一般情况,所以我不能做出那个决定


有什么想法吗?

看起来您正试图在参数中描绘值。我建议使用引号以外的内容,并添加引号。例如,使用tildes:

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

cscript myscript.vbs //Nologo "1 ~2 3~"
0 = 1 "2 3"
你有两个选择

第一个很简单——使用克拉(^)来转义引号


第二个选项是使用不同的分隔符。在这样的命令中,shell使用空格作为参数之间的分隔符。但是shell允许使用分号、逗号、等号和制表符等其他字符。通过实现其中一个,您不需要用引号括住参数,因为空格将不再打断您的命令行。

看看这个问题:。也许有一些有用的答案。谢谢。我来看看。从WMI获取命令行可能就行了。我最终得到了这样的解决方案。