Я думаю, вы обнаружите, что ваш пример работает абсолютно нормально.
cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe" > "C:\temp\Folder Containing Spaces\SomeProgram.out"
Я воспроизвел ваш пример здесь
http://pastebin.com/raw.php?i=YtwQXTGN
C:\>cmd /c "c:\Program Files\my folder\my long program.exe" > "c:\temp\spaces are here\a.a"
C:\>type "c:\temp\spaces are here\a.a"
my long program.exe has run
C:\>
further example demonstrating it works with "my long program.exe", removing cmd /c, it operates fine too.
C:\>"c:\Program Files\my folder\my long program.exe" > "c:\temp\spaces are here\
a.a"
C:\>type "c:\temp\spaces are here\a.a"
my long program.exe has run
C:\>
Another example, but with replace. replace with no parameters says "source path required" "no files replaced"
C:\>replace > a.a
Source path required
C:\>type a.a
No files replaced
Exactly the same effect when they're in folders with spaces.
C:\>cmd /c "c:\Program Files\my folder\replace.exe" > "c:\temp\spaces are here\r.r"
Source path required
C:\>type "c:\temp\spaces are here\r.r"
No files replaced
C:\>
further demonstration with replace
without cmd /c works fine too.
C:\>"c:\Program Files\my folder\replace.exe" > "c:\temp\spaces are here\r.r"
Source path required
C:\>type "c:\temp\spaces are here\r.r"
No files replaced
C:\>
Причина, по которой ваш пример работает нормально
cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe" > "C:\temp\Folder Containing Spaces\SomeProgram.out"
и то, как / почему он работает так, как работает, потому что> хост интерпретируется как> специальный. Так что эта часть cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe"
- я думаю - оценивается первой. т.е. cmd / c не видит> и после.
смд /? показывает 2 случая
Случай 1 и Случай 2. Ваш пример подходит для случая 1
If /C or /K is specified, then the remainder of the command line after
the switch is processed as a command line, where the following logic is
used to process quote (") characters:
1. If all of the following conditions are met, then quote characters
on the command line are preserved:
- no /S switch
- exactly two quote characters
- no special characters between the two quote characters,
where special is one of: &<>()@^|
- there are one or more whitespace characters between the
two quote characters
- the string between the two quote characters is the name
of an executable file.
2. Otherwise, old behavior is to see if the first character is
a quote character and if so, strip the leading character and
remove the last quote character on the command line, preserving
any text after the last quote character.
Вы можете проверить, что ваш пример соответствует случаю 1, потому что если вы добавите / s (без добавления дополнительных кавычек или внесения каких-либо изменений в ваш пример, кроме добавления / s), то вы получите другой результат, потому что это делает ваш пример хитом 2. Таким образом, это доказывает, что ваш пример определенно является случаем 1. И он явно соответствует всем критериям варианта 1.
Если в вашем примере был случай 2, а вы добавили / s, то это не имеет значения.
Ваш ответ интересен, потому что он показывает альтернативный способ получения вашего результата, но в случае 2. Добавив дополнительные внешние цитаты и добавив /s.
Но на самом деле, когда вы добавляете эти дополнительные внешние кавычки, вы только что сделали это вариантом 2, и добавление / s поверх этого не будет иметь значения.
C:\>cmd /c "c:\Program Files\my folder\replace.exe"
Source path required
No files replaced
C:\>cmd /s /c "c:\Program Files\my folder\replace.exe"
'c:\Program' is not recognized as an internal or external command,
operable program or batch file.
C:\>cmd /c ""c:\Program Files\my folder\replace.exe""
Source path required
No files replaced
C:\>cmd /s /c ""c:\Program Files\my folder\replace.exe""
Source path required
No files replaced
C:\>
Пример в вашем вопросе работал нормально
cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe" > "C:\temp\Folder Containing Spaces\SomeProgram.out"
Ваш вариант (с / S и внешними кавычками), который вы даете в качестве ответа, чтобы пример работал, тоже отлично работает
cmd.exe /S /C ""C:\Program Files\Somewhere\SomeProgram.exe" > "C:\temp\Folder Containing Spaces\SomeProgram.out""
Хотя ваш ответ, который является альтернативой, на самом деле можно упростить, удалив / S, потому что это уже случай 2, поэтому добавление / s не будет иметь никакого значения. Так что это улучшит решение, приведенное в вашем ответе
cmd.exe /C ""C:\Program Files\Somewhere\SomeProgram.exe" > "C:\temp\Folder Containing Spaces\SomeProgram.out""
Ваш пример, который вы назвали проблемой в своем вопросе, и ваше решение дают одинаково хороший результат. Но я полагаю, что есть одно большое различие (и я не уверен, как это проверить), но одно отличие в том, как работает ваш пример и как работает решение в вашем ответе, я думаю, что в случае вашего примера, cmd.exe хостинга / вызова выполняет перенаправление в файл. В то время как в примере вашего решения вызываемый cmd.exe передается> узлом cmd.exe, и поэтому вызываемый cmd.exe выполняет перенаправление. Также, конечно, ваш пример - это случай 1, а ваше решение - это поправка, которую вы внесли (очень хорошо), чтобы она работала в случае 2.
Надеюсь, я здесь не ошибся, возможно. Но ваш вопрос и ответ помогли мне понять, как работает cmd и, в частности, cmd / c!
Возможно, ваш пример был упрощением вашего фактического, а ваш действительный потерпел неудачу и нуждался в вашей поправке. Если ваш пример был немного более сложным, например, с параметром для программы, которая принимает кавычки, то он бы потерпел неудачу в случае 1, и вам действительно потребуются внешние кавычки (/ S не изменит результат , поэтому нет необходимости в / S, так как это уже будет случай 2, когда вы добавите необходимые внешние кавычки). Но пример, который вы привели в своем вопросе, на самом деле мне кажется, работает нормально.
Добавлено - связанные вопросы и ответы Для чего используется cmd / s?