MSBuild远程Web部署中的App_Offline [英] App_Offline in MSBuild Remote Web Deploy

查看:107
本文介绍了MSBuild远程Web部署中的App_Offline的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在MSBuild脚本中具有以下任务,以使用Web Deploy(MSDeploy服务)部署到远程服务器:

I have the following task in my MSBuild script to deploy to a remote server using Web Deploy (MSDeploy service):

  <Target Name="Deploy">
    <MSBuild
            Projects="$(SolutionFile)"
            Properties="Configuration=Release; DeployOnBuild=True; 
              DeployTarget=MsDeployPublish; MSDeployPublishMethod=WMSvc; 
              MsDeployServiceUrl=$(DeployServiceUrl); 
              DeployIisAppPath=$(DeployIisAppPath); 
              UserName=$(DeployUserName); Password=$(DeployPassword); 
              CreatePackageOnPublish=True; AllowUntrustedCertificate=True" />
  </Target>

工作正常.但是,我想在部署应用程序之前放置一个app_offline.htm文件(在远程服务器上),并在部署之后(或出错时)删除app_offline.htm文件.是否有MSBuild属性或任何其他脚本调整可以使其实现?

It works fine. However, I would like to place an app_offline.htm file (on the remote server) before the app is deployed and remove the app_offline.htm file after deployment (or on error). Is there a MSBuild property or any other scripting tweak to make it happen?

谢谢.

推荐答案

我最近在 http://sedodream.com/2012/01/08/HowToTakeYourWebAppOfflineDuringPublishing.aspx .这比应该做的要困难得多,我正在努力简化它以用于更高版本.无论如何,我都会为您粘贴所有内容.

I just recently blogged about this at http://sedodream.com/2012/01/08/HowToTakeYourWebAppOfflineDuringPublishing.aspx. It's more difficult than it should be and I'm working on simplifying that for a later version. In any case I've pasted all the content here for you.

我收到了一封客户电子邮件,询问他们如何在从Visual Studio进行发布的整个过程中使他们的Web应用程序/网站脱机.使您的站点脱机的一种简单方法是将一个app_offline.htm文件拖放到站点根目录中.有关您可以阅读ScottGu的帖子的更多信息,请在资源部分的下面链接.不幸的是,Web Deploy本身不支持此功能.如果您希望Web Deploy(aka MSDeploy)本地支持此功能,请在

I received a customer email asking how they can take their web application/site offline for the entire duration that a publish is happening from Visual Studio. An easy way to take your site offline is to drop an app_offline.htm file in the sites root directory. For more info on that you can read ScottGu’s post, link in below in resources section. Unfortunately Web Deploy itself doesn’t support this . If you want Web Deploy (aka MSDeploy) to natively support this feature please vote on it at http://aspnet.uservoice.com/forums/41199-general/suggestions/2499911-take-my-site-app-offline-during-publishing.

由于Web Deploy不支持此功能,因此会更加困难,并且需要我们执行以下步骤:

Since Web Deploy doesn’t support this it’s going to be a bit more difficult and it requires us to perform the following steps:

  1. 发布app_offline.htm
  2. 发布应用,并确保app_offline.htm包含在要发布的有效载荷之内
  3. 删除app_offline.htm

1 将使应用程序脱机,然后再开始发布过程.

1 will take the app offline before the publish process begins.

2 将确保在我们发布app_offline.htm时不会被删除(因此使应用程序保持脱机状态)

2 will ensure that when we publish that app_offline.htm is not deleted (and therefore keep the app offline)

3 将删除app_offline.htm,并使网站恢复在线状态

3 will delete the app_offline.htm and bring the site back online

现在我们知道需要做什么,让我们看一下实现.首先是简单的部分.在Web应用程序项目(WAP)中创建一个名为app_offline-template.htm的文件.该文件将最终成为目标服务器上的app_offline.htm文件.如果将其保留为空白,则用户将收到一条通用消息,指出该应用程序处于脱机状态,但最好在该文件内放置静态HTML (无ASP.NET标记),让用户使用知道该站点将重新启动,并且您认为与您的用户有关的任何其他信息.添加此文件时,应在属性"网格中将生成操作"更改为无".这将确保该文件本身没有被发布/打包.由于文件以.htm结尾,因此默认情况下将发布该文件.请参见下图.

Now that we know what needs to be done let’s look at the implementation. First for the easy part. Create a file in your Web Application Project (WAP) named app_offline-template.htm. This will be the file which will end up being the app_offline.htm file on your target server. If you leave it blank your users will get a generic message stating that the app is offline, but it would be better for you to place static HTML (no ASP.NET markup) inside of that file letting users know that the site will come back up and whatever other info you think is relevant to your users. When you add this file you should change the Build Action to None in the Properties grid. This will make sure that this file itself is not published/packaged. Since the file ends in .htm it will by default be published. See the image below.

现在是最困难的部分.对于Web应用程序项目,我们具有一个称为"wpp.targets"的发布/打包过程的钩子.如果要扩展发布/打包过程,可以在与项目文件本身相同的文件夹中创建一个名为{ProjectName} .wpp.targets的文件.这是我创建的文件,您可以将内容复制并粘贴到wpp.targets文件中.我将解释重要部分,但希望将整个文件发布以供您说服.注意:您可以从我的github存储库中获取此文件的最新版本,该链接位于下面的资源部分.

Now for the hard part. For Web Application Projects we have a hook into the publish/package process which we refer to as "wpp.targets". If you want to extend your publish/package process you can create a file named {ProjectName}.wpp.targets in the same folder as the project file itself. Here is the file which I created you can copy and paste the content into your wpp.targets file. I will explain the significant parts but wanted to post the entire file for your convince. Note: you can grab my latest version of this file from my github repo, the link is in the resource section below.

<?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命令是

1 Publish app_offline.htm

The implementation for #1 is contained inside the target PublishAppOfflineToDest. The msdeploy.exe command that we need to get executed is.

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目标内部,您可以通过为源和目标都创建一个项目来查看如何完成此目标.

In order to do this I will leverage the MSDeploy task. Inside of the PublishAppOfflineToDest target you can see how this is accomplished by creating an item for both the source and destination.

这部分是由片段完成的

<!--***********************************************************************
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包含在程序包中(但如果有的话也不是世界末日).

The item value for FilesForPackagingFromProject here will convert your app_offline-template.htm to app_offline.htm in the folder from where the publish will be processed. Also there is a condition on it so that it only happens during publish and not packaging. We do not want app_offline-template.htm to be in the package (but it’s not the end of the world if it does either).

MsDeploySkiprules的元素将确保app_offline-template.htm本身不会发布.这可能不是必需的,但不应该受到伤害.

The element for MsDeploySkiprules will make sure that app_offline-template.htm itself doesn’t get published. This may not be required but it shouldn’t hurt.

现在我们的应用程序已发布,我们需要从dest Web应用程序中删除app_offline.htm文件. msdeploy.exe命令为:

Now that our app is published we need to delete the app_offline.htm file from the dest web app. The msdeploy.exe command would be:

%msdeploy% -动词:删除 -dest:contentPath ="{IIS-Path}/app_offline.htm",computerName ="...",用户名="...",密码="..."

%msdeploy% -verb:delete -dest:contentPath="{IIS-Path}/app_offline.htm",computerName="...",username="...",password="..."

这是在DeleteAppOffline目标内部实现的.该目标将在发布后自动执行,因为我包含了属性AfterTargets ="MSDeployPublish".在该目标中,您可以看到我正在直接构建msdeploy.exe命令,看起来MSDeploy任务不支持删除动词.

This is implemented inside of the DeleteAppOffline target. This target will automatically get executed after the publish because I have included the attribute AfterTargets="MSDeployPublish". In that target you can see that I am building up the msdeploy.exe command directly, it looks like the MSDeploy task doesn’t support the delete verb.

如果您尝试这样做,请在遇到任何问题时通知我.我正在考虑从中创建一个Nuget软件包,以便您可以仅安装该软件包.这将需要一些工作,因此,如果您对此感兴趣,请告诉我.

If you do try this out please let me know if you run into any issues. I am thinking to create a Nuget package from this so that you can just install that package. That would take a bit of work so please let me know if you are interested in that.

  1. 我的AppOffline wpp的最新版本.targets文件
  2. ScottGu在app_offline.htm上的博客
  1. The latest version of my AppOffline wpp.targets file
  2. ScottGu’s blog on app_offline.htm

这篇关于MSBuild远程Web部署中的App_Offline的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆