2012-06-04 32 views
1

我无法弄清楚如何将值传递给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> 

我想重构消息任务为目标,然后越过VAR1和VAR2给它得到的结果相同。这是一个非常简单的例子,但概念是相同的。

+0

像[这](http://stackoverflow.com/q/7407400/147211) ? – KMoraz

+0

@KMoraz不,该帖子指的是延迟名称解析。我想要做的是将多个变量传递给一个目标,然后让目标进程处理每个变量,就像一个方法一样。 – oliwa

回答

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

是的!这正是我所追求的,但是在这样做的过程中,我发现了一个相关的问题。如果我在消息任务之后有另一个任务,则在继续执行下一个任务之前,将为消息项目组中的所有项目执行消息任务。如何获取任务A,任务B和任务C以便为ItemGroup中的每个项目运行? – oliwa

+0

我不知道这是否可能。最简单的方法是创建目标A,目标B和目标C,并让每个目标执行消息任务,然后执行您希望它运行的任务。否则,您可以编写自己的自定义MSBuild任务,并接收消息和目标/任务名称,然后像这样调用它 。在我看来,第一种选择似乎更容易。 – BryanJ

+2

目标配料可能(与基于任务的配料相反)。向目标元素添加一个Outputs =“%(Messages.Identity)”应该做到这一点,它将指示整个目标应该被分批处理,并且每个项目的执行都与值无关。 Sayed对此处的细分示例进行了很好的描述:http://www.sedodream.com/PermaLink,guid,cab57d7f-9d6e-4358-8491-dc033fb3bacc.aspx –

1

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

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

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

<?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 
相关问题