在MSBuild中替换Item的内容?

时间:2015-02-04 15:51:58

标签: c# .net build msbuild msbuild-task

我有一个项目列表,我希望在做任何事情之前以某种方式排序(例如在显示其内容之前)。我已经编写了一个自定义任务,它在目标中使用时工作正常,如下所示:

<Target Name="List">
  <SortProjects In="@(Projects)">
    <Output ItemName="SortedProjects" TaskParameter="Out"/>
  </SortProjects>
  <ListProjects In="@(SortedProjects)"/>
</Target>

这太棒了,但我真正想做的是修改@(Projects)本身,而不是制作一个新的项目:

<Target Name="List">
  <SortProjects In="@(Projects)">
    <Output ItemName="Projects" TaskParameter="Out"/>
  </SortProjects>
  <ListProjects In="@(Projects)"/>
</Target>

这样我可以把事情分成多个目标:

<Target Name="Sort">
  <SortProjects In="@(Projects)">
    <Output ItemName="Projects" TaskParameter="Out"/>
  </SortProjects>
</Target>

<Target Name="List">
  <ListProjects In="@(Projects)"/>
</Target>

然后我可以制作&#34;排序&#34;定位一个InitialTarget,以便在任何许多不同的目标之前自动运行,例如&#34; List&#34;我打算构建,而不是需要将SortProjects任务放入每个目标,如&#34; List&#34;。

不幸的是,当我尝试将输出定向到@(项目)时,它不会覆盖@(Projects)的内容;相反,它附加到他们身上。因此ListProjects列出了排序项目后面的未排序项目。我非常有信心这不是由于SortProjects任务中的一些明显的算法错误。

有没有办法替换内容而不是追加内容?或者,更一般地说,还有其他一些方法来完成我在这里尝试做的事情?谢谢。

2 个答案:

答案 0 :(得分:0)

您不需要每次都进行排序。只需使用DependsOnTargets属性指定在特定目标之前调用Sort目标。这样,如果你多次使用它,它只会被调用一次。

答案 1 :(得分:0)

使用项目的删除属性(仅适用于目标):

<Target Name="List">
  <SortProjects In="@(Projects)">
    <Output ItemName="SortedProjects" TaskParameter="Out"/>
  </SortProjects>
  <ItemGroup>
    <Projects Remove="@(Projects)"/>
    <Projects Include="@(SortedProjects)"/>
  </ItemGroup>
</Target>

请注意,即使在目标内定义,每个ItemGroup也属于全局范围。