Этот вопрос является дубликатом App_Offline в MSBuild Remote Web Deploy , но я вставил ответ ниже.MSDeploy v3 имеет прямую поддержку app_offline, но вам нужен MSDeploy v3 с обеих сторон.Мы еще не обновили интерфейс VS Web Publish, чтобы иметь возможность использовать это, но в какой-то момент мы сделаем обновление.
Я недавно писал об этом в http://sedodream.com/2012/01/08/HowToTakeYourWebAppOfflineDuringPublishing.aspx. Это сложнее, чемэто должно быть, и я работаю над упрощением этого для более поздней версии.В любом случае, я вставил сюда весь контент для вас.
Я получил электронное письмо от клиента с вопросом, как они могут перевести свое веб-приложение / сайт в автономный режим на все время публикации в Visual Studio.Простой способ перевести ваш сайт в автономный режим - это поместить файл app_offline.htm в корневой каталог сайтов.Для получения дополнительной информации об этом вы можете прочитать пост Скотту, ссылку ниже в разделе ресурсов.К сожалению, сам Web Deploy не поддерживает это.Если вы хотите, чтобы Web Deploy (он же MSDeploy) изначально поддерживал эту функцию, проголосуйте за нее по номеру http://aspnet.uservoice.com/forums/41199-general/suggestions/2499911-take-my-site-app-offline-during-publishing.
Поскольку Web Deploy не поддерживает это, это будет немного сложнее и требует от нас выполненияследующие шаги:
- Опубликовать app_offline.htm
- Опубликовать приложение и убедиться, что app_offline.htm содержится в публикуемой полезной нагрузке
- Удалить app_offline.htm
1 переведет приложение в автономный режим до начала процесса публикации.
2 обеспечит, чтобы при публикации этот app_offline.htm не удалялся (и, следовательно, оставлял приложение в автономном режиме),
3 удалятapp_offline.htm и вернуть сайт в оперативный режим
Теперь, когда мы знаем, что нужно сделать, давайте посмотрим на реализацию.Сначала для легкой части.Создайте файл в своем проекте веб-приложения (WAP) с именем app_offline-template.htm.Это будет файл, который в конечном итоге станет файлом app_offline.htm на целевом сервере.Если вы оставите это поле пустым, ваши пользователи получат общее сообщение о том, что приложение находится в автономном режиме, но было бы лучше, чтобы вы поместили статический HTML (без разметки ASP.NET) внутри этого файла, сообщая пользователям об этом.что сайт вернется и любую другую информацию, которая, по вашему мнению, имеет отношение к вашим пользователям.Когда вы добавляете этот файл, вы должны изменить действие сборки на «Нет» в сетке свойств.Это гарантирует, что сам этот файл не будет опубликован / упакован.Поскольку файл заканчивается на .htm, он будет по умолчанию опубликован.См. Изображение ниже.
Теперь о сложной части.Для проектов веб-приложений у нас есть хук в процессе публикации / упаковки, который мы называем «wpp.targets».Если вы хотите расширить процесс публикации / упаковки, вы можете создать файл с именем {ProjectName} .wpp.targets в той же папке, что и сам файл проекта.Вот файл, который я создал, вы можете скопировать и вставить содержимое в ваш файл wpp.targets.Я объясню важные части, но хотел опубликовать весь файл для вашего убеждения.Примечание: вы можете получить мою последнюю версию этого файла из моего репозитория github, ссылка находится в разделе ресурсов ниже.
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="InitalizeAppOffline">
<!--
This property needs to be declared inside of target because this is imported before
the MSDeployPath property is defined as well as others -->
<PropertyGroup>
<MSDeployExe Condition=" '$(MSDeployExe)'=='' ">$(MSDeployPath)msdeploy.exe</MSDeployExe>
</PropertyGroup>
</Target>
<PropertyGroup>
<PublishAppOfflineToDest>
InitalizeAppOffline;
</PublishAppOfflineToDest>
</PropertyGroup>
<!--
%msdeploy%
-verb:sync
-source:contentPath="C:\path\to\app_offline-template.htm"
-dest:contentPath="Default Web Site/AppOfflineDemo/app_offline.htm"
-->
<!--***********************************************************************
Make sure app_offline-template.htm gets published as app_offline.htm
***************************************************************************-->
<Target Name="PublishAppOfflineToDest"
BeforeTargets="MSDeployPublish"
DependsOnTargets="$(PublishAppOfflineToDest)">
<ItemGroup>
<_AoPubAppOfflineSourceProviderSetting Include="contentPath">
<Path>$(MSBuildProjectDirectory)\app_offline-template.htm</Path>
<EncryptPassword>$(DeployEncryptKey)</EncryptPassword>
<WebServerAppHostConfigDirectory>$(_MSDeploySourceWebServerAppHostConfigDirectory)</WebServerAppHostConfigDirectory>
<WebServerManifest>$(_MSDeploySourceWebServerManifest)</WebServerManifest>
<WebServerDirectory>$(_MSDeploySourceWebServerDirectory)</WebServerDirectory>
</_AoPubAppOfflineSourceProviderSetting>
<_AoPubAppOfflineDestProviderSetting Include="contentPath">
<Path>"$(DeployIisAppPath)/app_offline.htm"</Path>
<ComputerName>$(_PublishMsDeployServiceUrl)</ComputerName>
<UserName>$(UserName)</UserName>
<Password>$(Password)</Password>
<EncryptPassword>$(DeployEncryptKey)</EncryptPassword>
<IncludeAcls>False</IncludeAcls>
<AuthType>$(AuthType)</AuthType>
<WebServerAppHostConfigDirectory>$(_MSDeployDestinationWebServerAppHostConfigDirectory)</WebServerAppHostConfigDirectory>
<WebServerManifest>$(_MSDeployDestinationWebServerManifest)</WebServerManifest>
<WebServerDirectory>$(_MSDeployDestinationWebServerDirectory)</WebServerDirectory>
</_AoPubAppOfflineDestProviderSetting>
</ItemGroup>
<MSdeploy
MSDeployVersionsToTry="$(_MSDeployVersionsToTry)"
Verb="sync"
Source="@(_AoPubAppOfflineSourceProviderSetting)"
Destination="@(_AoPubAppOfflineDestProviderSetting)"
EnableRule="DoNotDeleteRule"
AllowUntrusted="$(AllowUntrustedCertificate)"
RetryAttempts="$(RetryAttemptsForDeployment)"
SimpleSetParameterItems="@(_AoArchivePublishSetParam)"
ExePath="$(MSDeployPath)" />
</Target>
<!--***********************************************************************
Make sure app_offline-template.htm gets published as app_offline.htm
***************************************************************************-->
<!-- We need to create a replace rule for app_offline-template.htm->app_offline.htm for when the app get's published -->
<ItemGroup>
<!-- Make sure not to include this file if a package is being created, so condition this on publishing -->
<FilesForPackagingFromProject Include="app_offline-template.htm" Condition=" '$(DeployTarget)'=='MSDeployPublish' ">
<DestinationRelativePath>app_offline.htm</DestinationRelativePath>
</FilesForPackagingFromProject>
<!-- This will prevent app_offline-template.htm from being published -->
<MsDeploySkipRules Include="SkipAppOfflineTemplate">
<ObjectName>filePath</ObjectName>
<AbsolutePath>app_offline-template.htm</AbsolutePath>
</MsDeploySkipRules>
</ItemGroup>
<!--***********************************************************************
When publish is completed we need to delete the app_offline.htm
***************************************************************************-->
<Target Name="DeleteAppOffline" AfterTargets="MSDeployPublish">
<!--
%msdeploy%
-verb:delete
-dest:contentPath="{IIS-Path}/app_offline.htm",computerName="...",username="...",password="..."
-->
<Message Text="************************************************************************" />
<Message Text="Calling MSDeploy to delete the app_offline.htm file" Importance="high" />
<Message Text="************************************************************************" />
<ItemGroup>
<_AoDeleteAppOfflineDestProviderSetting Include="contentPath">
<Path>$(DeployIisAppPath)/app_offline.htm</Path>
<ComputerName>$(_PublishMsDeployServiceUrl)</ComputerName>
<UserName>$(UserName)</UserName>
<Password>$(Password)</Password>
<EncryptPassword>$(DeployEncryptKey)</EncryptPassword>
<AuthType>$(AuthType)</AuthType>
<WebServerAppHostConfigDirectory>$(_MSDeployDestinationWebServerAppHostConfigDirectory)</WebServerAppHostConfigDirectory>
<WebServerManifest>$(_MSDeployDestinationWebServerManifest)</WebServerManifest>
<WebServerDirectory>$(_MSDeployDestinationWebServerDirectory)</WebServerDirectory>
</_AoDeleteAppOfflineDestProviderSetting>
</ItemGroup>
<!--
We cannot use the MSDeploy/VSMSDeploy tasks for delete so we have to call msdeploy.exe directly.
When they support delete we can just pass in @(_AoDeleteAppOfflineDestProviderSetting) as the dest
-->
<PropertyGroup>
<_Cmd>"$(MSDeployExe)" -verb:delete -dest:contentPath="%(_AoDeleteAppOfflineDestProviderSetting.Path)"</_Cmd>
<_Cmd Condition=" '%(_AoDeleteAppOfflineDestProviderSetting.ComputerName)' != '' ">$(_Cmd),computerName="%(_AoDeleteAppOfflineDestProviderSetting.ComputerName)"</_Cmd>
<_Cmd Condition=" '%(_AoDeleteAppOfflineDestProviderSetting.UserName)' != '' ">$(_Cmd),username="%(_AoDeleteAppOfflineDestProviderSetting.UserName)"</_Cmd>
<_Cmd Condition=" '%(_AoDeleteAppOfflineDestProviderSetting.Password)' != ''">$(_Cmd),password=$(Password)</_Cmd>
<_Cmd Condition=" '%(_AoDeleteAppOfflineDestProviderSetting.AuthType)' != ''">$(_Cmd),authType="%(_AoDeleteAppOfflineDestProviderSetting.AuthType)"</_Cmd>
</PropertyGroup>
<Exec Command="$(_Cmd)"/>
</Target>
</Project>
1 Опубликовать app_offline.htm
Реализация для # 1содержится внутри целевого объекта PublishAppOfflineToDest.Команда msdeploy.exe, которую нам нужно выполнить:.
msdeploy.exe
-source:contentPath='C:\Data\Personal\My Repo\sayed-samples\AppOfflineDemo01\AppOfflineDemo01\app_offline-template.htm'
-dest:contentPath='"Default Web Site/AppOfflineDemo/app_offline.htm"',UserName='sayedha',Password='password-here',ComputerName='computername-here',IncludeAcls='False',AuthType='NTLM' -verb:sync -enableRule:DoNotDeleteRule
. Для этого я использую задачу MSDeploy.Внутри цели PublishAppOfflineToDest вы можете увидеть, как это достигается путем создания элемента как для источника, так и для места назначения.
2 Опубликуйте приложение и убедитесь, что app_offline.htm содержится в публикуемой полезной нагрузке
Эта часть выполнена фрагментом
<!--***********************************************************************
Make sure app_offline-template.htm gets published as app_offline.htm
***************************************************************************-->
<!-- We need to create a replace rule for app_offline-template.htm->app_offline.htm for when the app get's published -->
<ItemGroup>
<!-- Make sure not to include this file if a package is being created, so condition this on publishing -->
<FilesForPackagingFromProject Include="app_offline-template.htm" Condition=" '$(DeployTarget)'=='MSDeployPublish' ">
<DestinationRelativePath>app_offline.htm</DestinationRelativePath>
</FilesForPackagingFromProject>
<!-- This will prevent app_offline-template.htm from being published -->
<MsDeploySkipRules Include="SkipAppOfflineTemplate">
<ObjectName>filePath</ObjectName>
<AbsolutePath>app_offline-template.htm</AbsolutePath>
</MsDeploySkipRules>
</ItemGroup>
Элементзначение для FilesForPackagingFromProject здесь преобразует ваш app_offline-template.htm в app_offline.htm в папке, из которой будет обрабатываться публикация. Также существует условие, чтобы это происходило только во время публикации, а не упаковки. Мы не хотим, чтобы app_offline-template.htm был в пакете (но это не конец света, если он тоже).
Элемент для MsDeploySkiprules гарантирует, что сам app_offline-template.htm не будет опубликован. Это может не требоваться, но не должно быть больно.
3 Удалить app_offline.htm
Теперь, когда наше приложение опубликовано, нам нужно удалить файл app_offline.htm из веб-приложения dest. Команда msdeploy.exe будет выглядеть следующим образом:
% MSDeploy%
-verb: удалить
-dest: contentPath = "{IIS-Path} /app_offline.htm", computerName = "...", имя пользователя = "...", пароль = "..."
Это реализовано внутри цели DeleteAppOffline. Эта цель будет автоматически выполнена после публикации, потому что я включил атрибут AfterTargets = ”MSDeployPublish”. В этой цели вы видите, что я создаю команду msdeploy.exe напрямую, похоже, что задача MSDeploy не поддерживает глагол удаления.
Если вы попробуете это, пожалуйста, дайте мне знать, если у вас возникнут какие-либо проблемы. Я думаю создать пакет Nuget, чтобы вы могли просто установить этот пакет. Это займет немного работы, поэтому, пожалуйста, дайте мне знать, если вы заинтересованы в этом.
Ресурсы
- Последняя версия моего файла AppOffline wpp.targets
- Блог ScottGu на app_offline.htm