Использование msbuild для выполнения профиля публикации файловой системы

У меня есть проект С#.Net 4.0, созданный с VS2010 и теперь доступ к которому осуществляется с помощью VS2012.

Я пытаюсь опубликовать только необходимые файлы с этого сайта в место назначения (C:\builds\MyProject [Files])

Моя файловая структура: . /ProjectRoot/MyProject.csproj ./ProjectRoot/Properties/PublishProfiles/FileSystemDebug.pubxml

Я запускаю следующее через MSBuild:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe./ProjectRoot/MyProject.csproj/p: DeployOnBuild = true/p:PublishProfile=./ProjectRoot/Properties/PublishProfiles/FileSystemDebug.pubxml

Здесь xml в FileSystemDebug.pubxml

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WebPublishMethod>FileSystem</WebPublishMethod>
    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish />
    <ExcludeApp_Data>False</ExcludeApp_Data>
    <publishUrl>C:\builds\MyProject\</publishUrl>
    <DeleteExistingFiles>True</DeleteExistingFiles>
  </PropertyGroup>
</Project>

Полученное поведение:

  • здесь создается zip файл: ./ProjectRoot/obj/Debug/Package/MyProject.zip
  • Ничего не развертывается в <publishUrl>C:\builds\MyProject\</publishUrl> WTF
  • Созданный zip файл представляет собой завтрак свиней и полный файлов, которые не нужны для приложения.

Когда я запускаю этот профиль публикации через визуальную студию, папка создается в * C:\builds\MyProject * и содержит точные артефакты, которые я хочу.

Как получить этот простой результат из msbuild?

Ответ 1

К сведению: у меня была та же проблема с Visual Studio 2015. После многих часов попыток я теперь могу сделать msbuild myproject.csproj/p:DeployOnBuild=true/p:PublishProfile=myprofile.

Мне пришлось отредактировать мой файл .csproj, чтобы он заработал. Он содержал такую строку:

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" 
  Condition="false" />

Я изменил эту строку следующим образом:

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v14.0\WebApplications\Microsoft.WebApplication.targets" />

(Я изменил 10.0 на 14.0, не уверен, было ли это необходимо. Но я определенно должен был удалить условную часть.)

Ответ 2

Нашел ответ здесь: http://www.digitallycreated.net/Blog/59/locally-publishing-a-vs2010-asp.net-web-application-using-msbuild

В Visual Studio 2010 появилось отличное новое издание веб-приложений которые позволяют легко публиковать проект веб-приложения с помощью нажмите кнопку. За кулисами преобразование Web.config и создание пакета осуществляется массивом MSBuild script, который импортируется в файл проекта (найти по адресу: C:\Program Files (X86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets). К сожалению, script чрезвычайно сложный, грязный и недокументированные (другие, затем некоторые из-неправильно написанные и в основном бесполезные комментарии в файле). Большая блок-схема этого файла и некоторые документация о том, как подключиться к ней, будет приятной, но, похоже, (или, по крайней мере, я не могу найти его).

К сожалению, это означает выполнение публикации через командную строку гораздо более непрозрачно, чем должно быть. Я был удивлен отсутствием документации в этой области, поскольку в эти дни многие магазины используют сервер непрерывной интеграции, а некоторые даже делают автоматическое развертывание (что широковещательные функции VS2010 могут очень помочь), поэтому я подумал бы, что включение этого (легко!) было бы довольно основное требование для этой функции.

В любом случае, после того, как вы пробрались через Microsoft.Web.Publishing.targets файл часами и ударяя головой о стену проб и ошибок, Мне удалось выяснить, как Visual Studio, похоже, выполняет магия одним щелчком мыши "Публикация в файловую систему" ​​и "Развертывание сборки" Пакет ". Я буду разбираться в скриптах MSBuild, поэтому если вы не знакомы с MSBuild, я предлагаю вам проверить этот сбой курса MSDN.

Опубликовать в файловой системе

Опубликован файл VS2010 для публикации в файловой системе. мне немного, чтобы гасить, потому что я ожидал некоторого разумного использования MSBuild происходить. Вместо этого VS2010 делает что-то довольно странное: он вызывает на MSBuild для выполнения своего рода полуразвертывания, которое готовит веб-интерфейс файлы приложений в ваших проектах obj-папке, то, похоже, это руководство копия этих файлов (т.е. вне MSBuild) в вашу целевую публикацию папка. Это действительно потрясающее поведение, потому что MSBuild предназначен для копировать файлы вокруг (и другие связанные с построением вещи), поэтому itd имеет смысл если весь процесс был только одной целью MSBuild, которую VS2010 называл на, а не на цель, а затем на ручную копию.

Это означает, что выполнение этого через MSBuild в командной строке не является просто как вызов вашего файла проекта с определенной целью и устанавливая некоторые свойства. Вам нужно сделать то, что VS2010 должно иметь done: создайте цель самостоятельно, которая выполняет полуразвертывание, затем копирует результаты в целевую папку. Чтобы изменить файл проекта, щелкните правой кнопкой мыши по проекту в VS2010 и выберите" Разгрузить проект ", затем щелкните правой кнопкой мыши и нажмите" Изменить". Прокрутите вниз, пока не найдете Элемент импорта, который импортирует цели веб-приложения (Microsoft.WebApplication.targets; этот файл сам импортирует Файл Microsoft.Web.Publishing.targets, упомянутый ранее). Под эта строка хорошо добавляет нашу новую цель, называемую PublishToFileSystem:

<Target Name="PublishToFileSystem"
        DependsOnTargets="PipelinePreDeployCopyAllFilesToOneFolder">
    <Error Condition="'$(PublishDestination)'==''"
           Text="The PublishDestination property must be set to the intended publishing destination." />
    <MakeDir Condition="!Exists($(PublishDestination))"
             Directories="$(PublishDestination)" />

    <ItemGroup>
        <PublishFiles Include="$(_PackageTempDir)\**\*.*" />
    </ItemGroup>

    <Copy SourceFiles="@(PublishFiles)"
          DestinationFiles="@(PublishFiles->'$(PublishDestination)\%(RecursiveDir)%(Filename)%(Extension)')"
          SkipUnchangedFiles="True" />
</Target>

Эта цель зависит от PipelinePreDeployCopyAllFilesToOneFolder - это то, что VS2010 до того, как он выполнит свою ручную копию. Некоторые копают в Microsoft.Web.Publishing.targets показывает, что вызов этой цели вызывает файлы проекта, которые должны быть помещены в каталог, указанный свойство _PackageTempDir.

Первой задачей, которую мы вызываем в нашей целевой задаче, является задача "Ошибка", на которой weve установил условие, которое гарантирует, что задача будет выполняться только в том случае, если свойство PublishDestination не установлено. Это вас поймает и выйдите из строя в случае, если вы забыли указать Свойство PublishDestination. Затем мы вызываем задачу MakeDir для создания этот каталог PublishDestination, если он еще не существует.

Затем мы определяем элемент, называемый PublishFiles, который представляет все файлы, найденные в папке _PackageTempDir. Тогда задача Копировать который копирует все эти файлы в папку "Опубликовать назначения". Атрибут DestinationFiles в элементе Copy является немного сложным; он выполняет преобразование элементов и преобразует их пути в новые пути, установленные в папке PublishDestination (ознакомьтесь с хорошо известными Пункт Метаданные, чтобы увидеть, что означают эти%() s).

Чтобы вызвать эту цель из командной строки, мы можем просто выполнить эта команда (очевидно, изменение имени и свойств файла проекта для вас):

msbuild Website.csproj "/p:Platform=AnyCPU;Configuration=Release;PublishDestination=F:\Temp\Publish" /t:PublishToFileSystem

Ответ 3

У меня все еще была проблема после того, как вы попытались ответить на все выше сказанное (я использую Visual Studio 2013). Ничего не было скопировано в папку публикации.

Было обнаружено, что если я запускаю MSBuild с отдельным проектом вместо решения, я должен добавить дополнительный параметр, который указывает версию Visual Studio:

/p:VisualStudioVersion=12.0

12.0 для VS2013, замените версию, которую вы используете. Как только я добавил этот параметр, он просто сработал.

Полная командная строка выглядит так:

MSBuild C:\PathToMyProject\MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=MyPublishProfile /p:VisualStudioVersion=12.0

Я нашел его здесь:

http://www.asp.net/mvc/overview/deployment/visual-studio-web-deployment/command-line-deployment

Они заявляют:

Если вы укажете отдельный проект вместо решения, вам нужно добавить параметр, который указывает версию Visual Studio.

Ответ 4

Мне кажется, что ваш профиль публикации не используется и делает некоторую стандартную упаковку. Цели Microsoft Web Publish выполняют все то, что вы делаете выше, оно выбирает правильные цели на основе конфигурации.

У меня не осталось проблем с этапа TeamCity MSBuild, но я задал явный путь к профилю, вам просто нужно называть его по имени без .pubxml(например, FileSystemDebug). Он будет найден до тех пор, пока в стандартной папке, которая у вас есть.

Пример:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe ./ProjectRoot/MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=FileSystemDebug

Примечание. Это было сделано с использованием версий объектов Microsoft Web Publish для Visual Studio 2012, обычно расположенных в папке "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web". Проверьте папку развертывания для целевых типов типов развертывания, которые используются

Ответ 5

К сведению: та же проблема с запуском на сервере сборки (Дженкинс с установленной msbuild 15, запущенной из VS 2017 в веб-проекте .NET Core 2.1).

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

Итак, моя команда msbuild началась с:

msbuild /t:restore;build;publish

Это правильно инициировало процесс публикации, но ни одна комбинация или вариант "/p: PublishProfile = FolderProfile" никогда не работали для выбора профиля, который я хотел использовать ("FolderProfile").

Когда я прекратил использовать цель публикации:

msbuild /t:restore;build /p:DeployOnBuild=true /p:PublishProfile=FolderProfile

Я (по глупости) подумал, что это не будет иметь никакого значения, но как только я использовал переключатель DeployOnBuild, он правильно подобрал профиль.

Ответ 6

Сначала проверьте версию Visual Studio для ПК разработчика, которая может опубликовать решение (проект). как показано для VS 2013

 /p:VisualStudioVersion=12.0

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

Таким образом, полный код будет выглядеть примерно так:

"C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe" "C:\Program Files (x86)\Jenkins\workspace\Jenkinssecondsample\MVCSampleJenkins\MVCSampleJenkins.csproj"/T: Build; Package/p: Конфигурация = DEBUG/p: OutputPath = "obj\DEBUG"/p: DeployIisAppPath = "Веб-сайт по умолчанию /jenkinsdemoapp"/p:VisualStudioVersion=12.0

Ответ 7

На самом деле я объединил все ваши ответы с моим собственным решением, как решить вышеуказанную проблему:

  1. Я создаю файл pubxml в соответствии с моими потребностями
  2. Затем я копирую все параметры из файла pubxml в свой список параметров "/p: foo = bar" для msbuild.exe
  3. Я выбрасываю файл pubxml

Результат таков:

msbuild/t:restore/t:build/p:WebPublishMethod=FileSystem/p:publishUrl=C:\builds\MyProject\/p:DeleteExistingFiles=True/p:LastUsedPlatform="Any CPU"/p:Configuration=Release