2011-03-02 21 views
2

所以我有點在MSBuild中寫作的竅門。如何使用MSBuild ItemGroup成員作爲單獨的項目,如屬性?

我喜歡在ItemGroups中存儲事物的想法,因爲它很容易迭代,並且可以有多個字段。

這使得它們有點像一個類(更像結構體),但它們以一種感覺像lambda表達式的方式響應目標和任務的迭代語法。

但是我繼續遇到這種情況,我想訪問項目組中特定項目的值,即像訪問屬性一樣訪問它。

在這種情況下,我遇到了如何隔離組中單個項目的問題。

當項目組在目標或任務中進行批處理時,由於使用元數據名稱尋址或由於使用公共項目組名稱尋址,因此可以使用「當前」項目的值,即@(ItemsName)或%(MetaDataName)。

但我想要做的事情是:使用Item組作爲System.Configuration類,它包含配置文件的一部分中的條目的值。因此,正常情況下,將ItemGroup自身命名爲與配置文件中的節名相匹配。但是,ItemGroup不是可通過構建引擎接口訪問的可尋址元素,只有項目本身是可尋址的。

單獨命名項目組中的項目可能會很好,而不是將它們命名爲完全相同,並使用包含或元數據字段來區分它們。這使得它們的行爲類似於屬性,因爲它們可以單獨作爲不同的項目進行尋址。所以你可以很容易地在條件中使用它們的值:'(UniqueItemName - >'%(Value)')。

但是,然後,可迭代的功能實質上丟失了。

爲了縮小這個範圍,假設我有一個配置文件,通過和xml任務讀取到一個Item組中,以便節中的元素名稱成爲項目組中項目的名稱和每個配置文件的屬性元素是成爲元數據屬性:

<configItemFlag name="displayDebugMessages" value="true" note="use with abandon" /> 
<configItemFlag name="displaySecurityValueMessages" value="false" note="use with caution" /> 

當我想在一個條件來測試這一點,我需要縮小它是這樣的:

<Messge Text="Debug Message: you are debugging!" Condition="'@(configItemFlag->'%(Name)')' == 'displayDebugMessages' AND '@(configItemFlag->'%(Value)')' == 'true'/> 

但是,這只是評估比較頻繁不會評估爲單個布爾值EAN。

那麼有沒有什麼辦法可以把它歸結爲一個可靠的測試?

回答

1

看來你似乎遇到了msbuild腳本語言的一些限制。你有沒有想過寫一個自定義任務來執行你正在尋找的?通過這種方式,您將能夠充分利用完整的編程語言來承擔您要執行的簡單條件檢查。

+0

我被迫同意。我相信你的回答表明,'擴展'包解決了開發人員希望在構建腳本中添加不直接關注正常VS解決方案或項目文件中指定的操作的邊界情況。這是擴展旨在使MSBuild成爲更通用的腳本語言。然而,你的回答指出,我所要求的是一種'注意力',這是一種針對語言核心特徵的擴展,在這種情況下,擴展到核心數據結構。 – 2011-03-04 18:31:40

3

這是否適合你所要做的工作?

<ItemGroup> 
    <ConfigItemFlag Include="displayDebugMessages"> 
    <Value>true</Value> 
    <Note>use with abandon</Note> 
    </ConfigItemFlag> 
    <ConfigItemFlag Include="displaySecurityValueMessages"> 
    <Value>false</Value> 
    <Note>use with caution</Note> 
    </ConfigItemFlag> 
</ItemGroup> 

<Target Name="Build"> 
    <Message 
    Condition=" 
     '%(ConfigItemFlag.Identity)' == 'displayDebugMessages' AND 
     '%(Value)' == 'true'" 
    Text="Debug Message: you are debugging, %(Note)!" 
    /> 
</Target> 

輸出:

Build: 
    Debug Message: you are debugging, use with abandon! 

(迴應評論)

...我可以提供給能夠使用元作爲屬性的唯一事情是不是所有的偉大,除非目標將在整個過程中大量使用它們。基本上,它涉及到通過批量處理項目併爲每個批次創建本地屬性來將每個項目展平爲屬性。

<Target Name="BuildOne" 
    Outputs="%(ConfigItemFlag.Identity)"> 
    <!-- flatten this batch to properties --> 
    <PropertyGroup> 
    <_Identity>%(ConfigItemFlag.Identity)</_Identity> 
    <_Value>%(ConfigItemFlag.Value)</_Value> 
    <_Note>%(ConfigItemFlag.Note)</_Note> 
    </PropertyGroup> 
    <!-- use meta as properties --> 
    <Message 
    Condition=" 
     '$(_Identity)' == 'displayDebugMessages' AND 
     '$(_Value)' == 'true'" 
    Text="Debug Message: you are debugging, $(_Note)!" 
    /> 
</Target> 
<Target Name="Build" DependsOnTargets="BuildOne" 
    /> 
+0

是的,這是一個好主意,這是我在大多數情況下所做的。但是我想要的是更簡化的事情,這樣可以減少遍歷項目中元數據之間關係的語法負擔,並且可以通過屬性允許的更直接的方式訪問要測試的值。 – 2011-03-04 18:26:49

相關問題