2012-06-04 38 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 
相關問題