2

我不知道如何将值传递到 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 传递给它以获得相同的输出。这是一个非常简化的示例,但概念是相同的。

4

2 回答 2

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
于 2012-06-05T13:12:38.487 回答
2

这是为了补充而不是取代@BryanJ 的回答

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

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

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

输出:

TestMessage:
  I will print the Text metadata property of Message1
  Hello from Message1
TestMessage:
  I will print the Text metadata property of Message2
  Hello from Message2
TestMessage:
  I will print the Text metadata property of Message3
  Hello from Message3
TestMessageGrouping:
  I will print the Text metadata property of all messages from Group 1
  Hello from Message1
  Hello from Message2
TestMessageGrouping:
  I will print the Text metadata property of all messages from Group 2
  Hello from Message3
于 2013-09-20T15:14:59.283 回答