我试图运行以下命令:
forfiles /p ..\Schemas /m *.xsd /c "cmd /c ""C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe @path /classes"""
但是,它失败:
ERROR: Invalid argument/option - 'Files'. Type "FORFILES /?" for usage.
这些也不起作用:
forfiles /p ..\Schemas /m *.xsd /c "cmd /c \"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe\" @path /classes" forfiles /p ..\Schemas /m *.xsd /c "cmd /c ^"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe^" @path /classes"
这肯定是失败的,因为传递给cmd
的path包含空格。 通常引用整个论点来解决这个问题。 但是,似乎没有办法通过双引号。
那么, 如何使用Windows forfiles命令的完整path运行命令?
在第一次尝试时,您试图在cmd /c
之后的整个命令行中添加引号(而不是仅限于可执行文件的路径),因为cmd
尝试查找并执行整行命令。 因此,您需要在xsd.exe
之后而不是在命令行结尾处立即移动结束语。
不过,一般来说,这里的主要问题是cmd
和forfiles
不同地处理引号。 forfiles
使用\"
来转义引用,但是cmd
并不关心反斜杠。另外,如果你的代码出现在括号内的代码块中,你的路径中的文字圆括号可能会引起麻烦,如果它们没有引用到cmd
最后, cmd
可能会尝试去除引号(意外),这可能会导致更多的问题。
为了解决所有这些问题,在/C
: forfiles
支持用0xHH
表示法的十六进制代码指定字符后,使用另一种为命令行提供文字引号的方法。 因此,在命令行被实际执行之前, 0x22
隐藏父cmd
实例的引号:
forfiles /p ..\Schemas /m *.xsd /c "cmd /c 0x220x22C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe0x22 @path /classes0x22"
这将导致执行以下命令行(使用"D:\Data\Schemas\sample.xsd"
作为@path
的示例值):
cmd /c ""C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe" "D:\Data\Schemas\sample.xsd" /classes"
最后,通过cmd
最外面的引号后,执行以下命令行:
"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe" "D:\Data\Schemas\sample.xsd" /classes
请注意, @
path以及@path
所有其他文件名和路径相关的@
-style变量forfiles
扩展为已引用的值。
最初,我完全忘记了cmd
试图去掉引号的事实。 克里托斯基里亚克的回答让我想起了这件事 。 所以如果你喜欢我的回答,请不要忘记给他们点数!
这不是在这里forfiles
的。 这是cmd.exe处理引号的方式。 它本质上是为了自己的利益而过于聪明。 CMD /C
命令可以将任意一行作为命令,包括一个包含空格的命令; 但是,如果在CMD /C
之后给出的命令行以引号开头,则会在尝试执行前从行中删除第一个和最后一个引号。 因此,这两条线是完全等价的:
cmd /c echo hello cmd /c "echo hello"
现在问题是在下面的命令中引号被剥离:
cmd /c "C:\Program Files\xyz\abc.exe" one two
为了使它做你想做的事情,你需要把整个东西放在引号中(内部引号不需要被转义):
cmd /c ""C:\Program Files\xyz\abc.exe" one two"
现在,您可以将其放入FORFILES
命令中。 FORFILES要求引号用\
来转义,所以我们需要写:
forfiles /c "cmd /c \"\"C:\Program Files\xyz\abc.exe\" one two\""
或者在你的具体情况下:
forfiles /p ..\Schemas /m *.xsd /c "cmd /c \"\"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe\" @path /classes\""
(请注意, CMD
所有引号都会被转义,但外部引号是FORFILES
因此不会被转义。)