【问题标题】:Replacing the contents of an Item in MSBuild?替换 MSBuild 中项目的内容?
【发布时间】:2015-04-04 05:27:08
【问题描述】:

我有一个项目列表,我想在对其进行任何操作之前以某种方式对其进行排序(例如,在显示其内容之前)。为此,我编写了一个自定义任务,在目标中使用时效果很好,如下所示:

<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>

然后我可以将“Sort”目标设为 InitialTarget,这样它就可以在我打算构建的许多不同目标(如“List”)之前自动运行,而不是需要将 SortProjects 任务放入每个目标中像“列表”这样的目标。

不幸的是,当我尝试将输出定向到@(Projects) 时,它不会覆盖@(Projects) 的内容;相反,它附加到它们。所以 ListProjects 列出了未排序的项目,然后是排序的项目。我很确定这不是由于 SortProjects 任务中的一些明显算法错误造成的。

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      使用项目的移除属性(仅适用于目标内部):

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-10
        • 2012-09-06
        • 2016-10-18
        • 1970-01-01
        • 2019-12-06
        相关资源
        最近更新 更多