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

592

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

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

JC.
источник

Ответы:

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".
)
gbjbaanb
источник
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)и т. Д.

CestLaGalere
источник
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) был указан как макрос, но не был назначен.

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

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

mawl
источник
7
Вы хотите использовать ConfigurationName. Это изображение ... действительно трудно понять со всеми пятнами.
Раввин Стелс