我覺得目前還不清楚究竟是在這裏發生了什麼。在我們回答你的問題之前,讓我們通過修改你的proj文件來看看發生了什麼。
下面是一個修改後的文件sample-no-error.proj,其中我刪除了錯誤部分,並在其中添加了一個Message任務。
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0" DefaultTargets="Build">
<ItemGroup>
<Example Include="Item1">
<Color>Blue</Color>
</Example>
<Example Include="Item2">
<Color>Red</Color>
</Example>
</ItemGroup>
<Target Name="Build"
Inputs="@(Example)"
Outputs="%(Example.Color).txt">
<Message Text="Inside of Build, color: %(Example.Color)" />
</Target>
</Project>
當我從命令行構建這個結果是。 由此我們可以看到目標本身被執行了兩次。這是因爲在目標上你用輸出=%(Example.Color).txt來裝飾它。當你使用%(...)你開始MSBuild批處理。有兩種配料方式;目標配料,任務配料。目標批處理是每個批次執行一個完整目標的地方(這是您在這裏執行的操作)。任務批處理是每個批次執行任務的地方。
我已經得到了另一個示例,除了我在Build目標中添加了一條額外的Message語句外,
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0" DefaultTargets="Build">
<ItemGroup>
<Example Include="Item1">
<Color>Blue</Color>
</Example>
<Example Include="Item2">
<Color>Red</Color>
</Example>
</ItemGroup>
<Target Name="Build"
Inputs="@(Example)"
Outputs="%(Example.Color).txt">
<Message Text="Inside of Build, color: %(Example.Color)" />
<Error Text="An error occurred during %(Example.Color)" />
<OnError ExecuteTargets="HandleErrors" />
</Target>
<Target Name="HandleErrors">
<Message Text="Inside of the HandleErrors target" />
<Message Text="Do some cleanup about %(Example.Color)" Importance="high" />
</Target>
</Project>
當我建立這個結果是。 基於此,我們可以看到Build目標被執行了一次,並且發生了一個錯誤,所以它沒有像上一個沒有錯誤的例子那樣第二次執行。之後,HandleErrors目標被踢入。在它內部遇到了該元素。
<Message Text="Inside of the HandleErrors target" />
並且該消息被髮送到記錄器(注意這只是被調用一次)。之後,它來了。
<Message Text="Do some cleanup about %(Example.Color)" Importance="high" />
現在這產生了兩條消息語句。這是因爲任務批量已經開始在這裏啓動。每個唯一的批量爲(紅色和藍色)的%(Example.Color)會調用該任務。所以我們知道目標只被調用一次(發生原始錯誤的地方),但是您將整個示例項目集傳遞給它。
如果你想知道哪個值產生了錯誤,你必須跟蹤你的構建目標。您可以將當前顏色放置在屬性中,然後將其引用到HandleErrors目標中。例如,看看下面的sample-id-errors.proj。
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0" DefaultTargets="Build">
<ItemGroup>
<Example Include="Item1">
<Color>Blue</Color>
</Example>
<Example Include="Item2">
<Color>Red</Color>
</Example>
</ItemGroup>
<Target Name="Build"
Inputs="@(Example)"
Outputs="%(Example.Color).txt">
<PropertyGroup>
<_LastUsedColor>%(Example.Color)</_LastUsedColor>
</PropertyGroup>
<Message Text="Inside of Build, color: %(Example.Color)" />
<Error Text="An error occurred during %(Example.Color)" />
<OnError ExecuteTargets="HandleErrors" />
</Target>
<Target Name="HandleErrors">
<Message Text="Inside of the HandleErrors target" />
<Message Text="The color which caused the error was: $(_LastUsedColor)"/>
</Target>
</Project>
在這裏你可以看到生成的裏面如果出現錯誤,我只是使用相同的屬性,它的目標內我只是設置的值的_LastUsedColor屬性,然後。當我建立這個文件的結果是。
我覺得這是你要完成的任務。如果你不知道它是如何工作的,那麼批次就相當混亂。我在網上有一堆關於批次的資源http://sedotech.com/resources#Batching.
啊哈!我沒有錯過我在HandleErrors目標中通過引用%(Example.Color)來執行任務批處理。當然,設置一個屬性只是我所需要的。感謝您的快速和奇妙的詳細迴應(併爲您的不可缺少的書:-)。 – 2011-12-29 21:48:57
當然沒問題。 – 2011-12-29 23:03:11