2013-04-04 2 views
3

Я пытаюсь сделать что-то похожее на Get Visual Studio to run a T4 Template on every build, используя cmd's forfiles, чтобы преобразовать каждый шаблон в VS2008.Почему forfiles проглатывает первый аргумент команды?

Если я исполняю

forfiles /m "*.tt" /s /c "\"%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\TextTransform.exe\" @file" 

тогда я получаю TextTransform.exe «s сообщение об ошибке (экран текста, объясняющий, что передать его в качестве аргументов).

Если я вместо этого выполнить

forfiles /m "*.tt" /s /c "cmd /c echo Transforming @path && \"%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\TextTransform.exe\" @file" 

, то он работает отлично.

Чтобы отладить это, я создал простую программу из командной строки, которая называется debugargs, которая просто печатает количество полученных им аргументов и их значения. Затем некоторые эксперименты показывают, что первая форма прямого прохождения команды до forfiles вызывает проглатывание первого аргумента. Например.

forfiles /m "*.tt" /s /c "debugargs.exe 1 2 3" 

дает OUTPUT

2 arguments supplied 
#1: 2 
#2: 3 

documentation Я был в состоянии найти достаточно редкие, и я не вижу никакого упоминания об этом как возможность. Это просто непонятная ошибка, или я чего-то не хватает?

+0

Интересно. Все образцы, которые я вижу в Интернете, используют '/ c" cmd/c ... "'; ни один из них не вызывает отдельный exe напрямую. –

+1

Странно.Я обнаружил, что если EIRER из первых двух параметров является EXE, тогда EXE будет запускать и принимать оставшиеся аргументы (например, param3 +). Если, однако, аргументы являются .BAT, тогда будет выполняться SECOND, получая параметры 3+ – Magoo

+0

@PeterWright, интересно наблюдение. Это немного сложнее. Смотря только в случаях, когда вторым параметром является 'exe': если первый параметр не является файлом, я получаю' ERROR: система не может найти указанный файл. '. Если первый параметр является, например, текстовый файл, который я получаю «ERROR:« test.txt », не является допустимым исполняемым». Таким образом, единственный манекен, который действительно работает, - это существующий файл '.bat' или' .cmd'. Bizarre. –

ответ

3

Это, как представляется, ошибка на пути forfiles вызывает .exe s. В ожидании я продлил мою программу debugargs, чтобы напечатать полную командную строку.

X:\MyProject>forfiles /m "*.tt" /s /c "debugargs.exe 1 2 @file" 

2 arguments supplied 
#1: 2 
#2: Urls.tt 
Full command line: 1 2 "Urls.tt" 

Таким образом, наиболее подходящим обходной путь будет в два раза имя исполняемого файла:

forfiles /m "*.tt" /s /c "debugargs.exe debugargs.exe 1 2 @file" 

Альтернативным решением является вызвать с cmd /c. Здесь следует отметить, что если вам нужно процитировать путь исполняемого файла (например, потому что он содержит пробел), вам потребуется дополнительный обходной путь от предваряя @:

forfiles /m "*.tt" /s /c "cmd /c @\"debugargs.exe\" 1 2 @file" 
+0

Какова цель символа '@' здесь? Я хотел использовать «FORFILES» с контуром исполняемого файла, содержащим пробелы, и не смог заставить его работать. Это похоже на символ '@', который разрешил использование '\ '', который я уже пробовал, но без '@' и без успеха. Есть ли место, где я мог бы получить дополнительную информацию об этом свойстве? Спасибо –

+0

К сожалению, я могу Не помню, я вообще не использую cmd: для предпочтения я использую cygwin bash. –

0

Я воспроизвел поведение в файлах файлов. Вы можете обойти с помощью CMD/с до команды, или вы могли бы перейти в PowerShell, где эквивалентная команда будет что-то вроде этого (не проверено):

get-childitem . -filter "*.tt" -recurse | foreach-object { 
    & "${ENV:CommonProgramFiles(x86)}\Microsoft Shared\TextTemplating\1.2\TextTransform.exe" "`"$($_.Name)`"" 
} 

Билл

+0

Я не думаю, что PowerShell является вариантом (если я не вызываю его из 'cmd'), потому что VS2008 сбрасывает команду, которую я передаю в исполняемый файл. –

0

Я боролся с этим, а также. Обход, который я нашел, - это просто добавить дополнительное пространство между командой и первым аргументом! Так где я пытался сделать:

FORFILES /s /m *.dll /c "python \"c:\path\to\script.py\" -t arg1 etc" 

питон пытался найти файл «arg1» для выполнения, но если я просто изменить его на:

FORFILES /s /m *.dll /c "python \"c:\path\to\script.py\" -t arg1 etc" 

это на самом деле работает!

Смежные вопросы