Как запускать события пост-сборки Visual Studio только для отладочной сборки


592

Как я могу ограничить запуск событий после сборки только для одного типа сборки?

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

Ответы:


746

События до и после сборки запускаются как пакетный скрипт. Вы можете сделать условное заявление о $(ConfigurationName).

Например

if $(ConfigurationName) == Debug xcopy something somewhere

7
странно, может быть, это только я, но я попытался добавить условие if, и теперь я получаю эту ошибку - ошибка с кодом 255
— Michael L

101
Я обнаружил, что вся команда должна быть в одной строке, или вы получите «выход с кодом 255»
— Робин Минто

7
Вы также можете использовать gotos / label для более полного решения (см. мой ответ от 24 июля)
— CestLaGalere

11
и вы можете использовать скобки с командой if (см. мой ответ для примера)
— gbjbaanb

1
Вы должны использовать «xcopy / Y», чтобы файл был перезаписан в целевом каталоге.
— Матиас

521

К вашему сведению, вам не нужно использовать goto. Команду shell IF можно использовать с круглыми скобками:

if $(ConfigurationName) == Debug (
  copy "$(TargetDir)myapp.dll" "c:\delivery\bin" /y
  copy "$(TargetDir)myapp.dll.config" "c:\delivery\bin" /y
) ELSE (
  echo "why, Microsoft, why".
)

62
Могу ли я также добавить, чтобы быть осторожным с открывающей скобкой, которая должна следовать сразу за оператором if, как будто на следующей строке будет
— выдан

37
Используйте "$(ConfigurationName)"(обратите внимание на кавычки), если вы получите код ошибки 255
— jgauffin

20
обратите внимание, что если вы используете "" вокруг $ (ConfigurationName), вам также понадобятся кавычки вокруг слова Debug - операторы IF команды оболочки очень .. буквальны ... когда дело доходит до сравнения строк.
— gbjbaanb

5
Примечание. Чтобы избавиться от 255, мне пришлось использовать "" вокруг $ (ConfigurationName) И удалить пробелы вокруг условия, например, если "$ (ConfigurationName)" == "Release" <- Без пробелов вокруг ==
— Fhilton

15
В моем случае с Visual Studio 2017 $(ConfigurationName)пусто (командная строка события после сборки). if "$(Configuration)" == "Debug"работал на меня. Кстати, если вы хотите сделать что-то во всех других конфигах, используйте if NOT "$(Configuration)" == "Debug".
— Ральф Хундевадт

125

Добавьте ваше событие пост сборки, как обычно. Затем сохраните ваш проект, откройте его в блокноте (или в вашем любимом редакторе) и добавьте условие в группу свойств PostBuildEvent. Вот пример:

<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <PostBuildEvent>start gpedit</PostBuildEvent>
</PropertyGroup>

5
Это работает, но заставляет вас делать все ваши дизайнерские работы для событий в исходном файле проекта. Другие объявления событий условной сборки также скрыты от IDE.
— Джозеф Дейгл

3
Я должен сказать, что это лучший ответ для меня, предпочтительный метод просто не работает.
— Майкл Л

8
Вам не нужно открывать его в блокноте, вы можете остаться в Visual Studio. Вы можете щелкнуть правой кнопкой мыши файл проекта, нажать «Разгрузить проект», затем снова щелкнуть правой кнопкой мыши и нажать «Изменить». Теперь вы можете редактировать файл {{csproj}} с использованием синтаксической раскраски. Снова щелкните правой кнопкой мыши, но теперь нажмите «Перезагрузить проект» для перезагрузки.
— Авель

1
Этот подход не расширял макросы в самой команде PostBuildEvent, когда я пытался это сделать. cd "$(ProjectDir)"расширен до cd "".
— Дэррил

3
В VS 2017 вы также можете сделать это с <Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$(ConfigurationName) == Debug"> <Exec Command="your command"/></Target>. Макропеременные и все работает как обычно.
— СЦ

106

В качестве альтернативы (поскольку события помещаются в пакетный файл, а затем вызываются), используйте следующее (в окне событий Build, а не в пакетном файле):

if $(ConfigurationName) == Debug goto :debug

:release
signtool.exe ....
xcopy ...

goto :exit

:debug
' Debug items in here

:exit

Таким образом, вы можете иметь события для любой конфигурации и по-прежнему управлять ими с помощью макросов, а не передавать их в пакетный файл, помните, что %1это так $(OutputPath)и т. Д.


6
Если у вас есть возможность взглянуть на часть вашего кода в рефлекторе, компилятор преобразует множество операторов switch / case в goto.
— StingyJack

10
Почти все компиляторы переводят код в более простые инструкции, такие как goto. И обратный инжиниринг не может объединить более простые инструкции в «красивые» более сложные инструкции, которые вы бы предпочли увидеть. Я не понимаю, как Microsoft заставляет нас использовать goto, или как это относится к этому посту.
— TamusJRoyce

1
@StingyJack: если вы посмотрите на скомпилированный код, вы увидите, что все это превращено в инструкции JMP :) Мне все равно, что делает компилятор под прикрытием, пока я пишу хорошо читаемый код. (не то, что с помощью goto иногда не очень легко читать)
— gbjbaanb

Если я помещаю свои команды после сборки в пакет, я получаю это сообщение об ошибке при нажатии build:Error 1 The command "C:\MyProject\postbuild.bat" exited with code 99. MyProject
— Себастьян

4
если хотите, можете убрать ifи использоватьgoto :$(ConfigurationName)
— Calimero100582

15

Visual Studio 2015: правильный синтаксис (оставьте его в одной строке):

if "$(ConfigurationName)"=="My Debug CFG" ( xcopy "$(TargetDir)test1.tmp" "$(TargetDir)test.xml" /y) else ( xcopy "$(TargetDir)test2.tmp" "$(TargetDir)test.xml" /y)

Нет ошибки 255 здесь.


3
держи его на одной линии
— Эрик Бол-Фейзот

Работает хорошо. Tks
— Vinicius Gonçalves

1
Ваша условная техника сработала лучше для меня. Тем не менее, это работало даже лучше без каких-либо условий и гораздо более кратко. копия "$ (ProjectDir) \ .. \ $ (ConfigurationName) \ MyFileName" "$ (TargetDir)"
— shawn1874

1
Ваш скрипт корректен, но мой скрипт позволяет копировать разные файлы для разных конфигураций.
— Эрик Бол-Фейзот

8

Начиная с Visual Studio 2019, современный .csprojформат поддерживает добавление условия непосредственно к Targetэлементу:

<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Debug'">
    <Exec Command="nswag run nswag.json" />
</Target>

Пользовательский интерфейс не предоставляет способ настроить это, но он, кажется, безопасно оставить Configurationатрибут на месте, если вы вносите изменения через пользовательский интерфейс.


Это сработало для меня в VS 2019, спасибо!
— BrandoTheBrave

Это действительно заслуживает того, чтобы быть выше, также они действительно должны обновить пользовательский интерфейс, чтобы позволить вам пометить конфигурацию сборки или, по крайней мере, добавить условие из свойств csproj.
— DeadlyChambers,

4

Вы можете передать имя конфигурации скрипту после сборки и проверить его там, чтобы увидеть, должен ли он работать.

Передайте имя конфигурации с помощью $(ConfigurationName).

Проверка основана на том, как вы реализуете шаг после сборки - это будет аргумент командной строки.


-1

Это работает для меня в Visual Studio 2015.

Я копирую все файлы DLL из папки, расположенной в папке библиотеки на том же уровне, что и папка моего решения, в целевой каталог создаваемого проекта.

Используя относительный путь из моего каталога проекта и поднимаясь по структуре папок в два шага с помощью .. \ .. \ lib

MySolutionFolder
.... MyProject
Lib

if $(ConfigurationName) == Debug (
xcopy /Y "$(ProjectDir)..\..\lib\*.dll" "$(TargetDir)"
) ELSE (echo "Not Debug mode, no file copy from lib")

-2

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


10
События сборки не относятся к какой-либо конфигурации при создании в IDE.
— Джозеф Дейгл

1
В VS2015 тоже не работает. Не настраивается для каждой конфигурации.
— Виллем

2
Это относится только к проектам C ++ в Visual Studio, но не к C #
— bytecode77

-3

В Visual Studio 2012 вы должны использовать (я думаю, в Visual Studio 2010 тоже)

if $(Configuration) == Debug xcopy

$(ConfigurationName) был указан как макрос, но не был назначен.

Введите описание изображения здесь

Сравните: макросы для команд и свойств сборки


7
Вы хотите использовать ConfigurationName. Это изображение ... действительно трудно понять со всеми пятнами.
— Раввин Стелс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.