Почему MSBuild игнорирует мою цель BeforePublish?

Я, должно быть, упускаю что-то очевидное здесь, но у меня есть это в конце моего веб-проекта ASP.NET MVC.csproj файл:

    [...]
    <Target Name="BeforePublish">
        <Error Condition="'foo'=='foo'" Text="test publish error" />
    </Target>
</Project>

Насколько я могу судить, это всегда должно вызывать сбой публикации с ошибкой. Тем не менее, если я загружаю проект, нажимаю на него правой кнопкой мыши и нажимаю «Опубликовать», публикация происходит без проблем. Что мне не хватает?

 Jez16 окт. 2012 г., 10:21
@AlexeyShcherbak TheBeforePublish цель задокументированаэта страница MSDNи это определено в моемMicrosoft.Common.targets файлы.
 seva titov15 окт. 2012 г., 22:23
Что произойдет, если вы выполнитеmsbuild.exe MyMvcProject.csproj /t:PublishOnly из командной строки VS2010?
 Alexey Shcherbak16 окт. 2012 г., 00:13
Вероятно, нет такой цели "BeforePublish" (кроме этой цели). Какую именно цель вы пытаетесь преодолеть с помощью этой конструкции?
 Dan Nolan16 окт. 2012 г., 11:45
Вероятно, Visual Studio напрямую вызывает пользовательские задачи (сборки) MSBuild, поэтому, к сожалению, нет способа перехватить цель публикации. До / AfterBuild, кажется, единственный выбор.
 Jez16 окт. 2012 г., 10:58
@SevaTitov Интересно; Я получаю ошибкуPublish is only valid for 'Windows Application' or 'Console Application' project types. - так что я думаю, когда вы щелкаете правой кнопкой мыши проект MVC в Visual Studio и нажимаете «Опубликовать», он не использует MSBuild? Это что-то встроенное в Visual Studio, что я не могу настроить?

Ответы на вопрос(3)

и я случайно добавил новый внутри комментариев, и поэтому он не был вызван. Глупая ошибка.

После этого я получил цель BeforePublish для работы в Visual Studio 2010.

<Target Name="BeforePublish">
 //insert awesome here
 </Target>

примечание: вы должны предоставить свой собственный удивительный :)

 Peter Mortensen30 мар. 2015 г., 22:39
Первая часть первого предложения не понятна. Ты можешь починить это?
Решение Вопроса

я пришел к ответу, который хорошо работает для Visual Studio 2010 и Visual Studio 2012; поместите это как раз перед концом вашего веб-приложения.csproj файл:

<Project...
    [...]
    <!-- The following makes sure we can't accidentally publish a non-Release configuration from within Visual Studio -->
    <Target Name="PreventNonReleasePublish2010" BeforeTargets="PipelinePreDeployCopyAllFilesToOneFolder" Condition="'$(BuildingInsideVisualStudio)'=='true' AND '$(VisualStudioVersion)'=='10.0'">
        <Error Condition="'$(Configuration)'!='Release'" Text="When publishing from Visual Studio 2010, you must publish the Release configuration!" />
    </Target>
    <Target Name="PreventNonReleasePublish2012" BeforeTargets="MSDeployPublish" Condition="'$(BuildingInsideVisualStudio)'=='true' AND '$(VisualStudioVersion)'=='11.0'">
        <Error Condition="'$(Configuration)'!='Release'" Text="When publishing from Visual Studio 2012, you must publish the Release configuration!" />
    </Target>
</Project>

Читайте дальше, чтобы увидеть мои мысли за этим ответом, но в основном он вращается вокруг того факта, что Visual Studio 2010 определяетPipelinePreDeployCopyAllFilesToOneFolder Цель, к которой можно подключиться, и Visual Studio 2012 определяет более «стандартный»MSDeployPublish Цель, чтобы зацепить.

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

AFAIR, «Опубликовать» из контекстного меню Visual Studio 2010 вызывает инструмент webdeploy \ msdeploy. Я немного поиграл, но мне совсем не понравилось. Если вы все еще хотите использовать эту функцию и вставить свою цель куда-то - вам нужно знать точную цель и ее свойство зависимости.

Проверьтеc:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets

Вы найдете две задачи - MSDeploy и VSMSDeploy. Последний звучит как раз для меня. Первый вообще не используется в этом файле. Но VSMSDeploy используется в трех разных целях: PackageUsingManifest, TestDeployPackageToLocal и MSDeployPublish. Опять последний звучит хорошо;)

<Target Name="MSDeployPublish" DependsOnTargets="$(MSDeployPublishDependsOn)">

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

<PropertyGroup>
    <MSDeployPublishDependsOn Condition="'$(MSDeployPublishDependsOn)'!=''">
        $(MSDeployPublishDependsOn);
        YourTargetName;
    </MSDeployPublishDependsOn>
  </PropertyGroup>

Если вы уже перешли на MSBuild 4.0, есть более простой способ зацепить вашу цель. Вам просто нужно указатьBeforeTarget приписывать. В нашем случае это будет так:

  <Target Name="MyTarget" BeforeTargets="MSDeployPublish">
        <Error Condition="'foo'=='foo'" Text="test publish error" />
  </Target>

Надеюсь, это поможет. Спросите, если у вас есть еще вопросы.

PS: я не проверял все это, потому что у меня нет среды, готовой к MSDeploy;)

NB: Я помню, что мне не рекомендовалось использовать MSDeploy для наших собственных продуктов, потому что это было довольно нелогичным для правильной настройки его длянепрерывная интеграция (CI) система. Может быть, я не очень хорош в этом, и ваше решение будет работать правильно. Но приступайте к MSDeploy осторожно.

 Jez17 окт. 2012 г., 15:05
Во-первых, Intellisense говорит мне, что этоBeforeTargets и нетBeforeTarget какTarget приписывать. Во-вторых, добавление, которое не сработало, к сожалению. Это все еще публикует ОК. :-(
 Alexey Shcherbak17 окт. 2012 г., 16:06
Для первого случая - это тоже ошибка. Исправлено сейчас
 Alexey Shcherbak17 окт. 2012 г., 18:28
Используйте <OnError ExecuteTargets = "SomeEmptyTarget" /> Этот совет взят из этого вопроса (вы также можете проголосовать за него;)):stackoverflow.com/questions/3297194/...
 Alexey Shcherbak17 окт. 2012 г., 15:54
Правильно, похоже, что я случайно удалил одну букву = (. Имя атрибута должно быть BeforeTargets. Я только что проверил его, и на моей консоли была ошибка публикации "test publish error".habrastorage.org/storage2/5a1/d4e/553/... Исправлено в основном ответе
 Jez17 окт. 2012 г., 18:11
Да, но даже когда я используюBeforeTargets атрибут, это ничего не меняет. Это все еще публикует.

что это будет работать в VS 2010, поскольку я только что протестировал это в VS 2012, но я обнаружил, что поместив цель в файл (ProjectDir) / Properties / PublishProfiles / (ProfileName) .pubxml как «AfterBuild» целевые работы. Например, он не срабатывает при сборке проекта, но срабатывает при публикации проекта.

Так что вместо того, чтобы положить

<Target Name="BeforePublish">
    <Error Condition="'foo'=='foo'" Text="test publish error" />
</Target>

в вашем .csproj файле попробуйте положить

<Target Name="AfterBuild">
    <Error Condition="'foo'=='foo'" Text="test publish error" />
</Target>

вместо этого в вашем .pubxml файле, и он должен сработать непосредственно перед публикацией.

 Alex19 июн. 2018 г., 15:08
Это спасло меня, upvote
 harley.33321 авг. 2015 г., 13:50
Проголосовано за то, что этот ответ демонстрирует метод инкапсуляции события, характерного для конкретного профиля публикации, с определением события (вместо помещения его в основной файл проекта).

Ваш ответ на вопрос