如何在MSBuild中批处理?

时间:2012-06-04 21:05:12

标签: msbuild

我无法弄清楚如何将值传递给MSBuild任务,就像我将方法一样。拿下以下项目文件......

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0" DefaultTargets="Main">
<PropertyGroup>
    <Var1>Foo</Var1>
    <Var2>Bar</Var2>
</PropertyGroup>

<Target Name="Main">
    <Message Text="$(Var1)" Importance="high" />
    <Message Text="$(Var2)" Importance="high" />
</Target>   
</Project>

我想将Message任务重构为目标,然后将Var1和Var2传递给它以获得相同的输出。这是一个非常简化的例子,但概念是相同的。

2 个答案:

答案 0 :(得分:3)

我想你想做这样的事情:

<ItemGroup>
  <Messages Include="Message1">
    <Text>Hello from Message1</Text>
  </Messages>
  <Messages Include="Message2">
    <Text>Hello from Message2</Text>
  </Messages>
</ItemGroup>

<Target Name="TestMessage">
  <Message Text="%(Messages.Text)"/>
</Target>

这会产生以下输出:

TestMessage:
  Hello from Message1
  Hello from Message2

答案 1 :(得分:2)

这是为了补充而不是取代@BryanJ’s answer

有两种类型的批处理。一个是Task batching,当您使用%(ItemName.MetaData)语法时会发生这种情况。您只需将此值指定为任务参数,就好像%(ItemName.MetaData)只会扩展为一个特定值。然后,MSBuild会多次自动执行任务,从而避免任务明确支持迭代项目列表。

另一种批处理类型是Target batching。当您使用Inputs的{​​{1}}和Outputs属性时,会发生目标批处理。要以一种每个项目只执行一次目标的方式批量处理任意一组项目,您可以指定<Target/>。重要的是Inputs="@(ItemName)" Outputs=%(Identity).bogus存在。批处理将查看%(Identity)Inputs的所有可能扩展,并根据这些扩展确定其批处理。因此,如果希望Target针对每个项目单独运行,则必须确保每个项目都获得唯一的扩展。我给@ BryanJ的代码修改了使用这种风格的目标批处理:

Outputs

带输出:

<?xml version="1.0"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0" DefaultTargets="all">
  <ItemGroup>
    <Messages Include="Message1">
      <Text>Hello from Message1</Text>
      <Group>1</Group>
    </Messages>
    <Messages Include="Message2">
      <Text>Hello from Message2</Text>
      <Group>1</Group>
    </Messages>
    <Messages Include="Message3">
      <Text>Hello from Message3</Text>
      <Group>2</Group>
    </Messages>
  </ItemGroup>
  <Target Name="all" DependsOnTargets="TestMessage;TestMessageGrouping" />
  <!--
      Use the Inputs/Outputs attributes to specify Target
      batching. The metadata value I am batching over is
      Identity. Since Identity is unique per item, this means the
      Target will get run in full once for every value in
      Messages. We provide something bogus for Outputs. It is
      important that our bogus values do not coincide with real
      filenames. If MSBuild finds a file with the name of a value
      in Outputs and another file, with an older timestamp,
      matching the corresponding value in Inputs, it will skip
      running this Target. (This is useful in many situations, but
      not when we want to just print out messages!)
  -->
  <Target Name="TestMessage" Inputs="@(Messages)" Outputs="%(Identity).bogus">
    <Message Text="I will print the Text metadata property of %(Messages.Identity)" />
    <Message Text="%(Messages.Text)" />
  </Target>
  <!--
      If you want to combine Task and Target batching, you can specify
      a different metadata value than Identity to group the items
      by. I use the Group metadata I specified in the ItemGroup.
  -->
  <Target Name="TestMessageGrouping" Inputs="@(Messages)" Outputs="%(Group).bogus">
    <Message Text="I will print the Text metadata property of all messages from Group %(Messages.Group)" />
    <!--
        Now, within the Target batch, we use Task batching to print
        all of the messages in our %(Messages.Group) at once.
    -->
    <Message Text="%(Messages.Text)" />
  </Target>
</Project>