Получение данных App_Data при запуске с нуля
@ tdykstra получил эта часть права . Чтобы получить App_Data (и ACL, установленные автоматически), я сделал следующее:
- Добавление файла-заполнителя в App_Data
- Установите действие сборки для содержимого в заполнителе (в моем файле заполнителя есть текст, чтобы люди, натыкаясь на него, узнали, почему оно там).
- Не отмечен «Исключить файлы из папки App_Data» на вкладке «Пакет / публикация в Интернете» свойств проекта в VS 2010
При этом моя папка App_Data будет создана и готова к использованию на сервере. Однако это приведет к тому, что все мои файлы будут удалены при повторной публикации. Это проблема № 2 в моем вопросе выше, и она очень похожа на этот другой вопрос SO вопрос / ответ .
Предотвращение удаления данных на сервере при последующих событиях публикации
В MsDeploy есть два механизма, которые могут запутаться (по крайней мере, я их перепутал):
- Исключая файлы
- MsDeploy пропустить правила
Они оба могут быть использованы для решения проблемы, в зависимости от сценария:
- @ tdykstra , вероятно, сработает, если вы:
- Заранее знать имена файлов в App_Data (например, база данных sqllite)
- Включите файлы в папку App_Data в вашем проекте
- Использование правил пропуска MsDeploy для указания MsDeploy полностью пропустить все удаления на сервере для этого каталога и файлов в этом каталоге. Это решает проблему во всех случаях, но намного сложнее.
Реализация правил пропуска MsDeploy
Чтобы реализовать правила пропуска, вам придется отказаться от щелчка правой кнопкой мыши, параметр Развернуть в VS 2010 в пользу щелчка правой кнопкой мыши, Пакет, перейти в командную строку, повторно переместить пакетный файл и запустить командную строку) , Если вы готовы смириться с этим (да, потому что я автоматизирую все это с помощью процесса КИ), вот подробности:
Отредактируйте файл проекта и добавьте следующее . Обратите внимание, что аргумент 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>
- Пакет, не развертывать проект. Это создаст zip-файл и файл .cmd в целевом каталоге (определяется как «Расположение, где будет создан пакет» на вкладке «Пакет / публикация в Интернете»). По умолчанию это obj \ Debug \ Package (или obj \ Release \ Package)
- Развертывание сайта с использованием полученного командного файла
В моем тестировании вы должны упаковать и запустить командный файл. Настройки файла проекта сообщат 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. Что я буду делать для окончательного решения:
- Измените мой скрипт сборки на использование / T: Package (сейчас это / T: MsDeploy)
- Запрограммируйте процедуру поиска / замены скрипта, чтобы изменить сгенерированный сценарий развертывания cmd
- Запустить измененный сценарий развертывания
Это действительно должно быть проще.
Обновление
Вот сценарий поиска / замены, который я придумал в 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), и он будет работать как положено.