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

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

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

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

14 ответов

Решение

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

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

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

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

например:

call MyBatch1.bat
call MyBatch2.bat

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

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

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

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

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

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

Добавление к womp:

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

%(Command)
echo foo

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

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

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

<PostBuildEvent>
    <Command>
        copy $(TargetPath) $(SolutionDIr)\bin1
        copy $(TargetPath) $(SolutionDIr)\bin2
    </Command>
</PostBuildEvent>

Подход, предложенный womp, работает в Visual Studio 2015/2017 (Windows), но не работает в Visual Studio для Mac (предварительный просмотр), который, кажется, выполняет только первую из команд. Единственный подход, который я нашел, работая в обеих версиях Visual Studio для Mac и Windows, заключался в цепочке 2 команд 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.

Замечание для таких идиотов, как я - есть кнопка "раскрывающийся список", чтобы вы могли редактировать команды как многострочный текст.

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

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

Миграция устаревшего проекта .NET в Visual Studio 2022. Обнаружено, что мне не удалось запустить несколько команд ни для предварительной сборки, ни для пост-сборки. Поведение не было последовательным при переключении между Debug/Release, даже если я правильно понял синтаксис. Я предполагаю, что здесь, возможно, ошибка.

В Debugконфигурации, это приведет к ошибке, независимо от того, что я пробовал. Код ошибки 2а также 4будучи наиболее распространенным в то время Releaseработал. Мне было трудно определить, что было синтаксической ошибкой, а что просто ошибкой. XCOPY /Y /Fотлично работал в CMD/PowerShell.

Выполнение нескольких команд становится возможным (даже с условными выражениями) только после «бублинга» команд. ( ... ).

т.е. исходя из этого

      copy $(TargetDir)x64\SQLite.Interop.dll $(TargetDir)SQLite.Interop_x64.dll
copy $(TargetDir)x86\SQLite.Interop.dll $(TargetDir)SQLite.Interop_x86.dll
if $(ConfigurationName) == Release (
    call "C:\Program Files (x86)\Microsoft SDKs\ClickOnce\SignTool\signtool.exe" sign /t http://timestamp.sectigo.com /fd sha256 $(TargetPath)
)
      (copy $(TargetDir)x64\SQLite.Interop.dll $(TargetDir)SQLite.Interop_x64.dll)
(copy $(TargetDir)x86\SQLite.Interop.dll $(TargetDir)SQLite.Interop_x86.dll)
(if $(ConfigurationName) == Release (
    call "C:\Program Files (x86)\Microsoft SDKs\ClickOnce\SignTool\signtool.exe" sign /t http://timestamp.sectigo.com /fd sha256 $(TargetPath)
))

Дополнительный лакомый кусочек, так как ( )являются специальными символами, если вам нужно их экранировать, используйте каретку, т.е. ^)

Stackoverflow: событие после сборки с несколькими комбинациями if/copy выполняется только в том случае, если первый файл не существует

В Visual Studio 2022 пользовательский интерфейс для указания событий до и после сборки немного изменился, но вы все равно можете указать несколько команд для запуска, поместив каждую в отдельную строку:

Вышеуказанное устанавливает следующее в вашем файле проекта:

        <Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Exec Command="echo Post 1&#xD;&#xA;echo Post 2" />
  </Target>

  <Target Name="PreBuild" BeforeTargets="PreBuildEvent">
    <Exec Command="echo Pre 1&#xD;&#xA;echo Pre 2" />
  </Target>

Который при сборке производит что-то похожее:

      1>------ Build started: Project: MyProject, Configuration: Debug Any CPU ------
1>You are using a preview version of .NET. See: https://aka.ms/dotnet-core-preview
1>Pre 1
1>Pre 2
1>MyProject -> D:\repos\MyProject\bin\Debug\net6.0\MyProject.dll
1>Post 1
1>Post 2

Вы можете запускать несколько команд/пакетных файлов в Visual Studio 2022.

Только береги не добавляй

      exit %errorlevel% 

в ваш пакетный файл, потому что это приведет к выходу cmd, и Visual Studio не будет выполнять дальнейшие события после сборки.

Если вы хотите вернуть коды выхода, используйте

      exit /b 

https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/exit

Просто добавьте префикс "вызов" в ваш пакетный скрипт. Так что операторы под Batch-скриптом также выполняются после возврата вызова из batch-скрипта.

call Script1.cmd
call Script2.bat
Другие вопросы по тегам