11

我对 msbuild 在 VS2008 Web 部署项目中的行为有一个奇怪的问题,我想知道为什么它似乎随机行为不端。

我需要从部署文件夹中删除一些应该只存在于我的开发环境中的文件。这些文件是在开发/测试期间由 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 项目组(这可能是它应该在的位置),但它给了我同样不可预测的结果。

有没有人经历过这个?难道我做错了什么?为什么会这样?

4

2 回答 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 部署项目。@(DeleteAfterBuild)将评估没有文件,因为文件夹中不存在$(OutputPath)文件,并且不会删除任何文件作为AfterBuild目标的一部分
  3. 构建 #2 - 构建 Web 部署项目。@(DeleteAfterBuild)将使用文件夹中的所有预期文件进行评估,$(OutputPath)并将文件作为AfterBuild目标的一部分删除
  4. 基本上我们现在回到第 2 阶段。重复。结果当然是可以预测的——不再挠头。

参考资料: 如何:动态创建项目组,MSBUILD 文件中项目的 延迟评估

于 2009-05-13T07:51:13.683 回答
0

我意识到这已经得到了回答,但我想我会加我的 5 美分。对于 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>
于 2010-03-18T21:59:26.310 回答