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

问题描述 投票:28回答:4

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

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

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

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

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

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

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

asp.net .net msdeploy
4个回答
19
投票

Getting App_Data deployed when starting from scratch

@tdykstra得到了this part right。要在那里获取App_Data(并自动设置ACL),我执行了以下操作:

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

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

Preventing data on the server from being deleted on subsequent publish events

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

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

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

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

Implementing MsDeploy skip rules

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

  1. Edit the project file and add the following。请注意,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>
  2. 包,不要部署项目。这将在目标目录中创建一个zip文件和.cmd文件(由Package / Publish Web选项卡上的“将创建包的位置”定义)。默认情况下,这是obj \ Debug \ Package(或obj \ Release \ Package)
  3. 使用生成的命令文件部署站点

在我的测试中,您必须打包并运行命令文件。项目文件调整将告诉msbuild将必要的-skip规则放入命令文件中。但是,直接从VS 2010 doesn't seem to run the command file使用“发布”功能(请参阅this walkthrough上的警告)...它直接调用msdeploy,似乎不遵守项目文件跳过规则。我相信这是VS使用msbuild -T:Package和msbuild -T:MsDeployPublish来构建项目之间的区别,但我还没有对此进行测试。

最后,命令文件不太正确,至少在VS 2010 SP1中是这样。有一个很好的描述this SO answer出了什么问题,但基本上,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

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


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


7
投票

我在Visual Studio中使用Publish Web对话框时设法使其工作。注意:它适用于任何文件夹,而不仅仅是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>

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

Using MsDeploy publish profile .pubxml to create an empty folder structure on IIS and skip deleting it with MsDeploySkipRules


0
投票

总结和简化Emil和Leniel以简洁的方式回答,如果您只是想允许App_Data部署添加和更新,但是防止删除,请将其添加到您的.pubxml

<Project>
  ...

  <PropertyGroup>
    <UseMSDeployExe>true</UseMSDeployExe>
    <ExcludeApp_Data>False</ExcludeApp_Data>
  </PropertyGroup>

  <Target Name="AddCustomSkipRules"
          AfterTargets="AddIisSettingAndFileContentsToSourceManifest">
    <Message Text="Adding Custom Skip Rules" />
    <ItemGroup>
      <MsDeploySkipRules Include="SkipDeleteAppData">
        <SkipAction>Delete</SkipAction>
        <ObjectName>filePath</ObjectName>
        <AbsolutePath>App_Data\\.*</AbsolutePath>
      </MsDeploySkipRules>
      <MsDeploySkipRules Include="SkipDeleteAppData">
        <SkipAction>Delete</SkipAction>
        <ObjectName>dirPath</ObjectName>
        <AbsolutePath>App_Data</AbsolutePath>
      </MsDeploySkipRules>
    </ItemGroup>
  </Target>
</Project>

真的需要<UseMSDeployExe>true</UseMSDeployExe>或者它会失败抱怨Unrecognized skip directive 'skipaction'

© www.soinside.com 2019 - 2024. All rights reserved.