Visual Studio: несколько команд после сборки?

102

Visual Studio 2008 позволяет мне объявить команду и прикрепить ее к событию после сборки проекта. Как и многие разработчики, я регулярно использую его для копирования файлов в выходной каталог приложения.

Я работаю над проектом, в котором мне нужно скопировать файлы из двух разных мест в два разных места назначения, и все это в рамках одного проекта. Другими словами, мне нужно вызвать две разные команды xcopy из одного и того же события после сборки. Похоже, что событие после сборки примет только одну команду, и что если мне нужно вызвать несколько команд, мне придется поместить команды в файл * .bat и вызвать его из события после сборки.

Это правильно, или есть более простой способ вызвать две команды из события после сборки? Заранее спасибо за вашу помощь.

Дэвид Винеман
источник

Ответы:

126

Вы можете ввести столько команд после сборки, сколько захотите. Просто разделите их символами новой строки.

Вот пример из одного из моих проектов.

Командная строка события после сборки

мать
источник
3
Включение снимка экрана полезно только в том случае, если вы собираетесь разместить его навсегда.
Amandalishus
1
@ OWenJ23 ... или в данном случае 'imageshack';)
Энтони Уолш,
29
Несмотря на то, что мои команды находятся в разных строках, они выполняются вместе, как если бы они были в одной строке.
Trevor
6
К сожалению, похоже, что, по крайней мере, VS2015 не сообщает об ошибке, если одна из промежуточных команд не работает ... он сообщает результат последней команды как результат этапа после сборки.
Johannes S.
3
Кажется, что это работает изнутри Visual Studio, но не поддерживается, если вы используете MsBuild на машине сборки TFS. MsBuild удаляет разрывы строк, а затем не выполняет команду из-за неправильного синтаксиса.
Jeff B
107

Важно: при выполнении командного файла вы должны использовать оператор "call" для того, чтобы следующие строки выполнялись. Если вы не используете "call", выполнение переходит в .bat и не возвращается к следующим строкам. То же, что и в командной строке DOS.

например:

call MyBatch1.bat
call MyBatch2.bat
хаха
источник
3
Этот совет применим к командам grunt и npm, поскольку они обе работают с пакетными файлами (grunt.cmd и npm.cmd).
Мэтт Варблоу
16

Есть еще один вариант: вы можете разделить команды с помощью &&. Например

copy $(TargetPath) d:\folder1 && copy $(TargetPath) d:\folder2

Это не совсем то же самое, что разделение с помощью новой строки: с &&, если предыдущая команда не удалась, следующая команда не запустится.

Разделение символами новой строки легче читать, поэтому вы должны предпочесть его. Однако я знаю хотя бы один случай, когда &&это пригодится. Это сценарий, когда вы используете листы свойств для выполнения различных шагов после сборки на разных машинах. VS 2008 не позволяет напрямую устанавливать PostBuildStep на листах свойств, но вы можете добавить пользовательский макрос с вашей командой и вызвать его из основных настроек проекта. Макрос состоит из одной строки, поэтому вы можете использовать &&там несколько команд.

Конь
источник
11

Каждая команда должна быть в отдельной строке. Однако я обнаружил, что если возникает ошибка при выполнении одной из этих команд, вся пост-сборка завершается ошибкой, и поэтому вам нужно будет пробовать каждую команду пост-сборки по одной для отладки.

Лиза
источник
2
«xcopy / f» покажет полное исходное и целевое имя файла, которое будет напечатано до сбоя, что упрощает диагностику нескольких команд xcopy, чем нескольких команд копирования.
yoyo
9

Разделение команд с помощью & или && или; не работает в VS2017. Не могу поверить, что такая простая функциональность недоступна в VS2017. Visual Studio пытается выполнить весь текст в окне события пост-сборки как одну строку. Единственный вариант для меня сейчас - создать пакетный скрипт, который мне не особенно нравится.

Индра
источник
1
Разделение команд с помощью && работает для меня в VS2017. Указание каждой команды в отдельной строке в редакторе VS2017 у меня не работает.
codeniffer
5

Добавление к WOMP «s ответ :

Если у вас есть несколько листов свойств с чем-то, что нужно сделать в одном событии сборки, вы можете сделать следующее, чтобы связать команды:

%(Command)
echo foo

где %(Command)заменяется на предыдущее значение команды.

Лично я делаю это для всех событий сборки, даже если в настоящее время у меня нет унаследованных команд, потому что это гарантирует, что не возникнет проблем, если я добавлю листы свойств позже.

Макс Трукса
источник
1
Это также работает с шагом пользовательской сборки. Кроме того, выполнение exitпакетного оператора в любом месте цепочки приводит к прерыванию цепочки. В самом деле, exit 1вызывает сбой сборки, exit 0просто прерывает шаг, и сборка продолжается.
Мартин Коннелл,
3

В Visual Studio 2017 вы можете сделать это:

<PostBuildEvent>
    <Command>
        copy $(TargetPath) $(SolutionDIr)\bin1
        copy $(TargetPath) $(SolutionDIr)\bin2
    </Command>
</PostBuildEvent>
Джонатан Виснер
источник
1
Я отредактировал .csproj и добавил <Command> </Command> вокруг двух моих команд событий postbuild. Похоже, это не сработало. Когда я посмотрел в Build Events в Visual Studio, он имел <Command> </Command> вокруг двух команд, но выдал ошибку сборки: команда "<Command xmlns =" ​​.. "> command1 command2 </Command>" вышел с кодом 255.
Джимми
2

Подход, предложенный womp, работает в Visual Studio 2015/2017 (Windows), но не работает в Visual Studio для Mac (предварительная версия), который, похоже, выполняет только первую из команд. Единственный подход, который я нашел работающим как в версиях Visual Studio для Mac, так и в Windows, заключался в объединении двух команд MSBuild:

<Target Name="AfterResolveReferences">
<Exec Command="path\MyFirstCommand.exe -parameters" />
</Target>
<Target Name="MySecondCommand" AfterTargets="AfterResolveReferences" >
<Exec Command="path\MySecondCommand.exe -parameters" />
</Target>

В приведенном выше примере используется событие AfterResolveReferences, но оно, очевидно, должно работать и для события PostBuild.

Crulex
источник
1

У этой проблемы нет хорошего решения. Идея вызова вызывает запуск других скриптов. Я заметил, что обнаружение ошибок не работает. Поместите «exit / b 1» в FailMe.cmd. Используйте «call FailMe.cmd» на этапах пост-сборки. Заметили, что сборка не завершается ошибкой? Я использую VS 2017 для создания проекта C #. Теперь попробуйте с "FailMe.cmd". Теперь сборка сообщает об ошибке.

Так что вам может быть лучше просто использовать один скрипт, если важен отчет об ошибках.

Ричард Медоуз
источник
-4

Просто добавьте префикс «вызов» к вашему пакетному сценарию. Таким образом, операторы под пакетным сценарием также выполняются после возврата вызова из пакетного сценария.

call Script1.cmd
call Script2.bat
msKing
источник