Как получить msdeploy для создания App_Data, если он не существует, но не удалить содержимое удаленного каталога? - PullRequest
28 голосов
/ 17 января 2012

У меня есть настройки приложения со следующими параметрами пакета / публикации в Интернете:

  • Только файлы, необходимые для запуска этого приложения
  • (не отмечено) Исключить сгенерированные символы отладки
  • (проверено) Исключить файлы из папки App_Data
  • (проверено) Включите все базы данных, настроенные на вкладке Пакет / публикация SQL - заметьте, у меня нет есть настроенные базы данных
  • (не отмечено) включает параметры IIS, настроенные в IIS Express

В проекте у меня есть настройка папки App_Data, в основном для обработки журналов приложений.

Я хотел бы увидеть (и ожидать) следующее поведение:

  1. При первоначальном развертывании на новом сервере приложение копируется и создается папка App_Data с разрешениями на запись, назначенными для приложения.
  2. При последующих развертываниях папка App_Data игнорируется, поскольку она уже существует, и проверяется «Исключить файлы из папки App_Data».

Однако msdeploy, по-видимому, не выполняет шаг № 1 (шаг 2 подходит, если я создаю папку вручную). Мне не удалось найти какую-либо документацию в Интернете, кроме этого без ответа, поэтому вопрос , кажется, подтверждает поведение, которое я вижу.

Как получить msdeploy для создания App_Data и назначить разрешения при начальном развертывании в этом сценарии?

Ответы [ 4 ]

19 голосов
/ 19 января 2012

Получение данных App_Data при запуске с нуля

@ tdykstra получил эта часть права . Чтобы получить App_Data (и ACL, установленные автоматически), я сделал следующее:

  1. Добавление файла-заполнителя в App_Data
  2. Установите действие сборки для содержимого в заполнителе (в моем файле заполнителя есть текст, чтобы люди, натыкаясь на него, узнали, почему оно там).
  3. Не отмечен «Исключить файлы из папки App_Data» на вкладке «Пакет / публикация в Интернете» свойств проекта в VS 2010

При этом моя папка App_Data будет создана и готова к использованию на сервере. Однако это приведет к тому, что все мои файлы будут удалены при повторной публикации. Это проблема № 2 в моем вопросе выше, и она очень похожа на этот другой вопрос SO вопрос / ответ .

Предотвращение удаления данных на сервере при последующих событиях публикации

В MsDeploy есть два механизма, которые могут запутаться (по крайней мере, я их перепутал):

  1. Исключая файлы
  2. MsDeploy пропустить правила

Они оба могут быть использованы для решения проблемы, в зависимости от сценария:

  1. @ tdykstra , вероятно, сработает, если вы:
    1. Заранее знать имена файлов в App_Data (например, база данных sqllite)
    2. Включите файлы в папку App_Data в вашем проекте
  2. Использование правил пропуска MsDeploy для указания MsDeploy полностью пропустить все удаления на сервере для этого каталога и файлов в этом каталоге. Это решает проблему во всех случаях, но намного сложнее.

Реализация правил пропуска MsDeploy

Чтобы реализовать правила пропуска, вам придется отказаться от щелчка правой кнопкой мыши, параметр Развернуть в VS 2010 в пользу щелчка правой кнопкой мыши, Пакет, перейти в командную строку, повторно переместить пакетный файл и запустить командную строку) , Если вы готовы смириться с этим (да, потому что я автоматизирую все это с помощью процесса КИ), вот подробности:

  1. Отредактируйте файл проекта и добавьте следующее . Обратите внимание, что аргумент AbsolutePath является регулярным выражением, так что вы можете получить причудливый способ:

    <Target Name="AddCustomSkipRules">
        <ItemGroup>
          <MsDeploySkipRules Include="SkipDeleteAppData">
            <SkipAction>Delete</SkipAction>
            <ObjectName>filePath</ObjectName>
            <AbsolutePath>$(_Escaped_PackageTempDir)\\App_Data\\.*</AbsolutePath>
            <XPath>
            </XPath>
          </MsDeploySkipRules>
          <MsDeploySkipRules Include="SkipDeleteAppData">
            <SkipAction>Delete</SkipAction>
            <ObjectName>dirPath</ObjectName>
            <AbsolutePath>$(_Escaped_PackageTempDir)\\App_Data\\.*</AbsolutePath>
            <XPath>
            </XPath>
          </MsDeploySkipRules>
        </ItemGroup>
    </Target>
    
  2. Пакет, не развертывать проект. Это создаст zip-файл и файл .cmd в целевом каталоге (определяется как «Расположение, где будет создан пакет» на вкладке «Пакет / публикация в Интернете»). По умолчанию это obj \ Debug \ Package (или obj \ Release \ Package)
  3. Развертывание сайта с использованием полученного командного файла

В моем тестировании вы должны упаковать и запустить командный файл. Настройки файла проекта сообщат msbuild о необходимости вставить в командный файл необходимое правило -skip. Однако использование функции «опубликовать» прямо из VS 2010 , похоже, не запускает командный файл (см. Предупреждение по в этом пошаговом руководстве ) ... он вызывает msdeploy напрямую и не вызывает не соблюдайте правила пропуска файла проекта. Я полагаю, что это различие между VS, использующим msbuild -T: Package и msbuild -T: MsDeployPublish для сборки проекта, но я не проверял это.

Наконец, командный файл не совсем корректен, по крайней мере в VS 2010 SP1. Есть отличное описание того, что идет не так в этом SO-ответе , но в основном VS (или, возможно, цель / t: Package является лучшим виновником) устанавливает командный файл для публикации на машине без указания сайт. Чтобы это исправить, вам нужно каким-то образом получить «? Site = sitename » (вероятно, это? Site = Default + Web + Site) для полного URL-адреса https://machine:8172/MsDeploy.axd?site=Default+Web+Site) на конце computerName аргумент.

Проблема, с которой я столкнулся, заключалась в том, что командному файлу (командному файлу) было трудно использовать site = что-либо в командной строке, поскольку он неправильно анализировал аргумент командной строки (даже если его экранировали). Я не вижу способа обойти эту проблему, кроме непосредственного изменения файла cmd, но для тестирования я скопировал вывод msdeploy.exe, который я видел из моего неудачного запуска теста, и изменил его так, чтобы он вызывал msdeploy.exe напрямую без сценария.

Теперь, когда это работает, я собираюсь включить это в процессы сборки CI. Что я буду делать для окончательного решения:

  1. Измените мой скрипт сборки на использование / T: Package (сейчас это / T: MsDeploy)
  2. Запрограммируйте процедуру поиска / замены скрипта, чтобы изменить сгенерированный сценарий развертывания cmd
  3. Запустить измененный сценарий развертывания

Это действительно должно быть проще.

Обновление

Вот сценарий поиска / замены, который я придумал в PowerShell:

(Get-Content "project.deploy.cmd") 
  -replace('^set _ArgComputerName=$'
           ,"set  ArgComputerName=https://server:8172/MsDeploy.axd?Site=Default+Web+Site") 
  | Out-File -Encoding ascii deploy.cmd

После запуска может быть вызван deploy.cmd (без параметра / M), и он будет работать как положено.

9 голосов
/ 18 января 2012

Web Deploy не создаст папку, если нет файлов для копирования в нее. Одним из обходных путей в вашем сценарии было бы не использовать флажок Исключить файлы из папки App_Data , поместить фиктивный файл в App_Data (например, файл .txt, в котором ничего нет) и указать правила исключения файлов. для всего, что у вас есть в папке App_Data (например, ваш файл .sdf).

Об исключении отдельных файлов (вы можете использовать подстановочные знаки) см. Первый вопрос в разделе часто задаваемых вопросов по развертыванию на MSDN:

http://msdn.microsoft.com/en-us/library/ee942158.aspx#can_i_exclude_specific_files_or_folders_from_deployment

Об использовании метода фиктивного файла для создания папки см. Как убедиться, что папка Elmah развернута в этом учебном пособии:

http://www.asp.net/web-forms/tutorials/deployment-to-a-hosting-provider/deployment-to-a-hosting-provider-configuring-project-properties-4-of-12

7 голосов
/ 22 мая 2014

Мне удалось заставить его работать при использовании диалога Publish Web из Visual Studio.Примечание: он работает для любой папки, а не только App_Data.

Это базовый профиль .pubxml:

<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit http://go.microsoft.com/fwlink/?LinkID=208121. 
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
<AfterAddIisSettingAndFileContentsToSourceManifest>AddCustomSkipRules</AfterAddIisSettingAndFileContentsToSourceManifest>
    <WebPublishMethod>MSDeploy</WebPublishMethod>
    <LastUsedBuildConfiguration>Local</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish />
    <ExcludeApp_Data>False</ExcludeApp_Data>
    <MSDeployServiceURL>localhost</MSDeployServiceURL>
    <DeployIisAppPath>SuperCoolAwesomeAppName</DeployIisAppPath>
    <RemoteSitePhysicalPath />
    <SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>
    <MSDeployPublishMethod>InProc</MSDeployPublishMethod>
    <EnableMSDeployBackup>False</EnableMSDeployBackup>
    <UserName />
    <_SavePWD>False</_SavePWD>
    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
  </PropertyGroup>

  <PropertyGroup>
    <UseMsDeployExe>true</UseMsDeployExe>
  </PropertyGroup>

  <Target Name="CreateEmptyFolders">
    <Message Text="Adding empty folders to Files" />
    <MakeDir Directories="$(_MSDeployDirPath_FullPath)\Files\Folder 1" />
    <MakeDir Directories="$(_MSDeployDirPath_FullPath)\Files\Folder 2" />
    <MakeDir Directories="$(_MSDeployDirPath_FullPath)\Files\Folder 3\Test"/>
  </Target>

  <Target Name="AddCustomSkipRules" DependsOnTargets="CreateEmptyFolders">
    <Message Text="Adding Custom Skip Rules" />
    <ItemGroup>
      <MsDeploySkipRules Include="SkipFilesInFilesFolder">
        <SkipAction>Delete</SkipAction>
        <ObjectName>filePath</ObjectName>
        <AbsolutePath>$(_DestinationContentPath)\\Files\\.*</AbsolutePath>
        <Apply>Destination</Apply>
      </MsDeploySkipRules>

      <MsDeploySkipRules Include="SkipFoldersInFilesFolders">
        <SkipAction></SkipAction>
        <ObjectName>dirPath</ObjectName>
        <AbsolutePath>$(_DestinationContentPath)\\Files\\.*\\*</AbsolutePath>
        <Apply>Destination</Apply>
      </MsDeploySkipRules>

    </ItemGroup>
  </Target>

</Project>

Вот подробный пост, объясняющий это:

Использование MsDeploy для публикации профиля .pubxml для создания пустой структуры папок в IIS и пропуска удаления с помощью MsDeploySkipRules

0 голосов
/ 20 августа 2018

Обобщая и упрощая ответы Эмиля и Лениэля в сжатой форме, если вы просто хотите разрешить развертывание App_Data для добавлений и обновлений, но запрещает удаление, добавьте это к своим .pubxml.

<Project>
  ...

  <PropertyGroup>
    <UseMSDeployExe>true</UseMSDeployExe>
    <ExcludeApp_Data>False</ExcludeApp_Data>
  </PropertyGroup>

  <Target Name="AddCustomSkipRules"
          AfterTargets="AddIisSettingAndFileContentsToSourceManifest">
    <Message Text="Adding Custom Skip Rules" />
    <ItemGroup>
      <MsDeploySkipRules Include="SkipDeleteAppData">
        <SkipAction>Delete</SkipAction>
        <ObjectName>filePath</ObjectName>
        <AbsolutePath>App_Data\\.*</AbsolutePath>
      </MsDeploySkipRules>
      <MsDeploySkipRules Include="SkipDeleteAppData">
        <SkipAction>Delete</SkipAction>
        <ObjectName>dirPath</ObjectName>
        <AbsolutePath>App_Data</AbsolutePath>
      </MsDeploySkipRules>
    </ItemGroup>
  </Target>
</Project>

<UseMSDeployExe>true</UseMSDeployExe> действительно нужно, иначе он не сможет жаловаться Unrecognized skip directive 'skipaction'.

...