2016-09-12 111 views
1

我試圖運行下面的命令:如何使用Windows forfiles命令的完整路徑運行命令?

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的路徑包含空格。你通常引用整個論點來解決這個問題。但是,似乎沒有辦法通過雙引號。

那麼,如何使用Windows forfiles命令的完整路徑運行命令?

回答

2

在你的第一次嘗試,你試圖把整個命令行左右(附加)引號cmd /c之後,而不是路徑,只可執行文件,這將失敗,因爲cmd試圖尋找並執行整個線作爲命令。因此,您需要在xsd.exe之後立即移動結束報價,而不是在命令行末尾。

儘管如此,總的來說,這裏的主要問題是cmdforfiles處理引號的方式不同。 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以及所有其他文件名和路徑相關的@-樣式變量forfiles擴展爲已引用的值。


最初,我完全忘記了cmd試圖去掉引號的事實。 Klitos Kyriacouanswer提醒了我;所以如果你喜歡我的回答,請不要忘記給他們點數!

2

這不是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所以不會被轉義。)