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

时间:2012-01-17 18:50:27

标签: asp.net .net msdeploy

我的应用程序设置包含以下打包/发布Web设置:

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

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

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

  1. 在初始部署到全新服务器时,将复制该应用程序并创建一个App_Data文件夹,并为该应用程序分配写入权限。
  2. 在后续部署中,将忽略App_Data文件夹,因为它已存在,并且已选中“从App_Data文件夹中排除文件”。
  3. 但是,msdeploy似乎没有执行步骤#1(如果我手动创建文件夹,则步骤2没问题)。除了unanswered so question之外,我一直无法在网上找到任何文件,这似乎证实了我所看到的行为。

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

4 个答案:

答案 0 :(得分:19)

从头开始时部署App_Data

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

  1. 在App_Data中添加占位符文件
  2. 将构建操作设置为占位符上的内容(我的占位符文件中包含文本,以便让人们绊倒它知道它为什么存在)。
  3. 未选中“在VS 2010中项目属性的”打包/发布“Web选项卡上”从App_Data文件夹中排除文件“
  4. 这会创建我的App_Data文件夹并准备在服务器上使用。但是,每当我重新发布时,它都会导致我的所有文件都被删除。这是我上面的问题中的问题#2,与其他SO question / answer非常相似。

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

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

    1. 排除文件
    2. MsDeploy跳过规则
    3. 这些都可以用来解决问题,具体取决于场景:

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

        要实施跳过规则,您必须放弃右键单击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. 使用生成的命令文件
        4. 部署站点

          在我的测试中,您必须打包并运行命令文件。项目文件调整将告诉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:包目标是一个更好的罪魁祸首)设置命令文件以发布到机器而不指定站点。要解决这个问题,你需要以某种方式获得“?site = sitename ”(可能这是?site = Default + Web + Site,对于https:// 机器的完整URL :8172 / MsDeploy.axd?site = Default + Web + Site)到computerName参数的末尾。

          我遇到的问题是命令文件(批处理文件)在命令行上使用site = anything很困难,因为它错误地解析了命令行参数(即使转义)。除了直接修改cmd文件之外,我没有看到解决此问题的方法,但是为了测试我复制了我从失败的测试运行中看到的msdeploy.exe输出并修改了它以直接调用msdeploy.exe而没有脚本。

          现在它正在运行,我的目的是将其用于我的CI构建过程。我将为最终解决方案做的是:

          1. 将我的构建脚本更改为使用/ T:Package(现在是/ T:MsDeploy)
          2. 使用脚本化搜索/替换例程更改生成的cmd部署脚本
          3. 运行更改的部署脚本
          4. 这真的应该更容易。

            <强>更新

            这是我在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选项),它将按预期工作。

答案 1 :(得分: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

答案 2 :(得分: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

答案 3 :(得分: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'