如何使用MSBuild/Web部署项目删除多个文件?

11

我在使用VS2008 Web Deployment Project时遇到了一个奇怪的问题,想知道为什么它似乎会随机出现错误。

我需要从部署文件夹中删除一些只应存在于我的开发环境中的文件。这些文件是由Web应用程序在开发/测试期间生成的,不包括在我的Visual Studio项目/解决方案中。

我正在使用以下配置:

<!--  Partial extract from Microsoft Visual Studio 2008 Web Deployment Project -->
<ItemGroup>
  <DeleteAfterBuild Include="$(OutputPath)data\errors\*.xml" /> <!-- Folder 1: 36 files -->
  <DeleteAfterBuild Include="$(OutputPath)data\logos\*.*" />    <!-- Folder 2: 2 files -->
  <DeleteAfterBuild Include="$(OutputPath)banners\*.*" />       <!-- Folder 3: 1 file -->
</ItemGroup>

<Target Name="AfterBuild">
  <Message Text="------ AfterBuild process starting ------" Importance="high" />
    <Delete Files="@(DeleteAfterBuild)">
      <Output TaskParameter="DeletedFiles" PropertyName="deleted" />
    </Delete>
    <Message Text="DELETED FILES: $(deleted)" Importance="high" />
  <Message Text="------ AfterBuild process complete ------" Importance="high" />
</Target>
我遇到的问题是,当我进行 Web 部署项目的构建/重建时,有时它会删除所有文件,但其他时候则不会删除任何东西!或者它只会删除 DeleteAfterBuild 项组中的三个文件夹中的一个或两个。构建过程决定是否删除文件似乎没有一致性。
当我编辑配置以仅包括“文件夹1”(例如)时,它会正确地删除所有文件。然后添加文件夹2和3,它开始按照我的要求删除所有文件。然后,在随机时间,我将重建该项目,它就不再删除任何文件!
我已经尝试将这些项目移动到 ExcludeFromBuild 项组中(可能应该在那里),但结果同样不可预测。
有人经历过这种情况吗?我做错了什么?为什么会发生这种情况?
2个回答

29

<ItemGroup> 在脚本加载并且 <Target> 处理之前被评估。

似乎有不止一种正确的方法 -

  1. <ItemGroup> 包含在 <Target> 内部,这样它应该会在正确的时间被评估。这适用于 MS-Build v3.5+。

  2. 使用 <CreateItem> 生成项目列表

此示例构建脚本-

<!-- Using ItemGroup -->
<Target Name="AfterBuild">
  <ItemGroup>
    <DeleteAfterBuild Include="$(OutputPath)data\errors\*.xml" />
  </ItemGroup>
  <Delete Files="@(DeleteAfterBuild)" />
</Target>

<!-- Using CreateItem -->
<Target Name="AfterBuild">
  <CreateItem Include="$(OutputPath)data\errors\*.xml">
    <Output TaskParameter="Include" ItemName="DeleteAfterBuild"/>
  </CreateItem>
  <Delete Files="@(DeleteAfterBuild)" />
</Target>
为了解释为什么删除过程会生成'不可预测'的结果-
1. 从干净的构建输出路径开始 2. 构建#1-构建Web部署项目。由于文件不存在于$(OutputPath)文件夹中,@(DeleteAfterBuild)将计算得出零个文件,并且不会作为AfterBuild目标的一部分删除任何文件 3. 构建#2-构建Web部署项目。@(DeleteAfterBuild)将评估位于$(OutputPath)文件夹中的所有预期文件,并将这些文件作为AfterBuild目标的一部分删除。 4. 基本上我们现在回到第2阶段。重复。结果当然是可预测的 - 不再需要思考。
参考资料: 如何:动态创建Item组, MSBUILD文件中项目的延迟评估

+1 - 我也遇到了同样的问题,这个回答非常完美。谢谢! - spot

0

我意识到这个问题已经有了答案,但我想再加上我的意见。对于 Web 部署项目,没有必要使用提供的目标,只需添加一个包含ExcludeFromBuild元素的项组。我在我的部署项目文件底部提供了相关部分以供参考。

  <Import Project="$(MSBuildExtensionsPath)\Microsoft\WebDeployment\v9.0\Microsoft.WebDeployment.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.WebDeployment.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="BeforeMerge">
  </Target>
  <Target Name="AfterMerge">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
  <ItemGroup>
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\obj\**\*.*" />
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\Properties\**\*.*" />
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\**\*.csproj*" />
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\**\*.resx" />
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\**\*.Publish.xml" />
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\LocalTestRun.testrunconfig" />
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\TestResults\**\*.*" />
  </ItemGroup>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接