应用程序在MSBuild远程Web部署中脱机

应用程序在MSBuild远程Web部署中脱机,msbuild,msdeploy,web-deployment,webdeploy,Msbuild,Msdeploy,Web Deployment,Webdeploy,我的MSBuild脚本中有以下任务要使用Web部署(MSDeploy服务)部署到远程服务器: 它很好用。但是,我希望在部署应用程序之前(在远程服务器上)放置一个app_offline.htm文件,并在部署后(或出现错误时)删除app_offline.htm文件。是否有MSBuild属性或任何其他脚本调整来实现它 提前谢谢。我最近在上发了一篇博客。这比应该的要困难得多,我正在为以后的版本简化它。无论如何,我已经把所有的内容都贴在这里了 我收到一封客户电子邮件,询问他们如何在Visual Stu

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


它很好用。但是,我希望在部署应用程序之前(在远程服务器上)放置一个app_offline.htm文件,并在部署后(或出现错误时)删除app_offline.htm文件。是否有MSBuild属性或任何其他脚本调整来实现它


提前谢谢。

我最近在上发了一篇博客。这比应该的要困难得多,我正在为以后的版本简化它。无论如何,我已经把所有的内容都贴在这里了

我收到一封客户电子邮件,询问他们如何在Visual Studio发布的整个过程中使其web应用程序/网站脱机。使站点脱机的一种简单方法是在站点根目录中删除app_offline.htm文件。有关这方面的更多信息,请阅读ScottGu的文章,链接到下面的参考资料部分。不幸的是,WebDeploy本身不支持这一点。如果您希望Web Deploy(又名MSDeploy)以本机方式支持此功能,请在上投票

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

  • 发布app_offline.htm
  • 发布应用程序,并确保正在发布的负载中包含app_offline.htm
  • 删除app_offline.htm
  • 1将在发布过程开始前使应用程序脱机

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

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

    现在我们知道了需要做什么,让我们看看实现。首先是简单的部分。在Web应用程序项目(WAP)中创建名为app_offline-template.htm的文件。这将是最终成为目标服务器上的app_offline.htm文件的文件。如果您将其留空,您的用户将收到一条通用消息,说明应用程序处于脱机状态,但最好将静态HTML(无ASP.NET标记)放在该文件中,让用户知道网站将恢复,以及您认为与您的用户相关的任何其他信息。添加此文件时,应在“属性”网格中将“生成”操作更改为“无”。这将确保此文件本身未发布/打包。由于文件以.htm结尾,因此默认情况下将发布该文件。见下图

    现在是最难的部分。对于Web应用程序项目,我们有一个到发布/包过程的挂钩,我们称之为“wpp.targets”。如果要扩展发布/包过程,可以在与项目文件本身相同的文件夹中创建名为{ProjectName}.wpp.targets的文件。这是我创建的文件,您可以将内容复制并粘贴到wpp.targets文件中。我将解释重要的部分,但想发布整个文件供您参考。注意:您可以从my github repo获取此文件的最新版本,链接位于下面的参考资料部分

    <?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>
    
    为了做到这一点,我将利用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>
    
    
    app_offline.htm
    文件路径
    
    

  • WebDeploy v3.0现在支持这一点。。您只需将此行添加到“Properties\PublishProfiles”中的发布配置文件中

    <EnableMSDeployAppOffline>true</EnableMSDeployAppOffline>
    
    true
    
    因此,生成的发布配置文件将如下所示

    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        <EnableMSDeployAppOffline>true</EnableMSDeployAppOffline>
        <WebPublishMethod>MSDeploy</WebPublishMethod>
        <MSDeployServiceURL>(removed)</MSDeployServiceURL>
        <DeployIisAppPath>Default Web Site</DeployIisAppPath>
        <AllowUntrustedCertificate>True</AllowUntrustedCertificate>
        <SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
        <DeployAsIisApp>False</DeployAsIisApp>
        <MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
        <UserName>sayedha</UserName>
        <ExcludeApp_Data>False</ExcludeApp_Data>
        <_SavePWD>True</_SavePWD>
      </PropertyGroup>
    </Project>
    
    
    真的
    MSDeploy
    (已删除)
    默认网站
    

    我已将其放在我的博客列表中,谢谢。msbuild.exe现在有一个名为-enableRule:AppOffline的参数,用于在发布网站之前使应用程序脱机。有没有办法从msbuild调用此选项?@SergeyZwezdin WebDeploy v 3.0(在服务器上)没有该选项。看见但它目前不支持自定义脱机文件。谢谢。除了msbuild调用没有添加密码之外,它几乎对我有效。在删除部分中,“$(密码)”不应该是“%”(AoDeleteAppOfflineDestProviderSetting.Password)。我也尝试过这种方式,但它仍然没有添加password@SzilardD$(MSDeployPath)和$(密码)似乎会导致问题。脚本在我的VS2012项目中找不到这些。我已经在上创建了一个包含$(MSDeployPath)的请求。如果将您的PW添加到脚本或pubxml中的PropertyGroup,将识别$(密码)。
    <EnableMSDeployAppOffline>true</EnableMSDeployAppOffline>
    
    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        <EnableMSDeployAppOffline>true</EnableMSDeployAppOffline>
        <WebPublishMethod>MSDeploy</WebPublishMethod>
        <MSDeployServiceURL>(removed)</MSDeployServiceURL>
        <DeployIisAppPath>Default Web Site</DeployIisAppPath>
        <AllowUntrustedCertificate>True</AllowUntrustedCertificate>
        <SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
        <DeployAsIisApp>False</DeployAsIisApp>
        <MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
        <UserName>sayedha</UserName>
        <ExcludeApp_Data>False</ExcludeApp_Data>
        <_SavePWD>True</_SavePWD>
      </PropertyGroup>
    </Project>