如果它不存在,如何让msdeploy创建App_Data,但是不删除远程目录的任何内容?

Emi*_*rch 28 .net asp.net msdeploy

我有一个应用程序设置与以下打包/发布Web设置:

  • 只运行此应用程序所需的文件
  • (未选中)排除生成的调试符号
  • (选中)从App_Data文件夹中排除文件
  • (选中)包括在"打包/发布SQL"选项卡中配置的所有数据库 - 注意我没有配置任何数据库
  • (未选中)包括IIS Express中配置的IIS设置

在项目中,我有一个App_Data文件夹设置,主要用于处理应用程序日志.

我希望看到(并期望)的行为如下:

  1. 在初始部署到全新服务器时,将复制应用程序并创建App_Data文件夹,并为应用程序分配写入权限.
  2. 在后续部署中,将忽略App_Data文件夹,因为它已存在并且已选中"从App_Data文件夹中排除文件".

但是,msdeploy似乎没有执行步骤#1(如果我手动创建文件夹,则步骤2没问题).除了这个没有答案的问题,我一直无法在网上找到任何文件,似乎证实了我看到的行为.

在这种情况下,如何让msdeploy创建App_Data并为初始部署分配权限?

Emi*_*rch 19

从头开始时部署App_Data

@tdykstra得到了这个部分.要在那里获取App_Data(并自动设置ACL),我执行了以下操作:

  1. 在App_Data中添加占位符文件
  2. 将构建操作设置为占位符上的内容(我的占位符文件中包含文本,让人们绊倒它知道它为什么存在).
  3. 在VS 2010中的项目属性的"打包/发布"Web选项卡上,未选中 "从App_Data文件夹中排除文件"

这将创建我的App_Data文件夹并准备在服务器上使用.但是,每当我重新发布时,它都会导致我的所有文件都被删除.这是我上面的问题中的问题#2,并且非常类似于其他SO 问题/答案.

防止在后续发布事件上删除服务器上的数据

MsDeploy中有两种机制可能会混淆(至少我把它们混淆了):

  1. 排除文件
  2. MsDeploy跳过规则

这些都可以用来解决问题,具体取决于场景:

  1. @ tdykstra的解决方案可能会起作用,如果你:
    1. 事先知道App_Data中文件的名称(例如sqllite数据库)
    2. 将文件包含在项目的App_Data文件夹中
  2. 使用MsDeploy跳过规则告诉MsDeploy完全跳过服务器上该目录和该目录中文件的所有删除.这解决了所有情况下的问题,但涉及的更多.

实现MsDeploy跳过规则

要实现跳过规则,您必须放弃右键单击VS 2010中的"部署"选项,转而右键单击"打包","打包","转入命令行","重新启动批处理文件"并运行命令行.如果您愿意忍受这种体验(我,因为我通过CI流程实现了自动化),以下是详细信息:

  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>
    
    Run Code Online (Sandbox Code Playgroud)
  2. 包,不要部署项目.这将在目标目录中创建一个zip文件和.cmd文件(由Package/Publish Web选项卡上的"将创建包的位置"定义).默认情况下,这是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 = anything很困难,因为它错误地解析了命令行参数(即使转义).除了直接修改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
Run Code Online (Sandbox Code Playgroud)

一旦运行,就可以调用deploy.cmd(没有/ M选项),它将按预期工作.


tdy*_*tra 9

如果没有要复制到的文件,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


Len*_*rri 7

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>
Run Code Online (Sandbox Code Playgroud)

这是一个详细的帖子解释它:

使用MsDeploy发布配置文件.pubxml在IIS上创建一个空文件夹结构,并使用MsDeploySkipRules跳过删除它