2009-06-02 3 views
28

Was ist der Unterschied ein Element in einem Ziel, wie dies zwischen dem Erstellen:CreateItem vs ItemGroup

<Target Name="DoStuff"> 
    <CreateItem Include="@(IntermediateAssembly)" > 
     <Output TaskParameter="Include" ItemName="FileWrites"/> 
    </CreateItem> 
</Target> 

und wie folgt aus:

<Target Name="DoStuff"> 
    <ItemGroup> 
     <FileWrites Include="@(IntermediateAssembly)" /> 
    </ItemGroup> 
</Target> 

Wann möchten Sie die eine oder andere und warum verwenden?

Antwort

27

In Versionen von MSBuild vor 3.5 konnten Sie keine Eigenschaften oder Elemente innerhalb von Zielen definieren (wie in Ihrem zweiten Beispiel). Stattdessen wurde eine Aufgabe verwendet (CreateItem und CreateProperty)

Wenn Sie ToolsVersion 3.5 verwenden, müssen Sie CreateItem nicht mehr verwenden (obwohl Sie dies immer noch tun können, wenn Sie dies bevorzugen).

Am Ende schaffen sie beide den gleichen Artikel, mit dem gleichen Umfang. Die Verwendung der zweiten Syntax ist besser lesbar und die Einrichtung benutzerdefinierter Metadaten ist meiner Meinung nach viel einfacher.

Hinweis: Die 3.5-Version von MSBuild wird mit .NET 3.5 installiert. Sie müssen ToolsVersion="3.5" in dem Tag Project Ihrer MSBuild-Datei definieren, um 3.5 Features zu verwenden.

Falls Sie sich wundern, bekam ich die meisten dieser Informationen aus dem Buch Inside the Microsoft® Build Engine: Using MSBuild and Team Foundation Build, die ich wirklich mochte (aber in keiner Weise angegliedert).

+0

Vielen Dank, das ist genau das, was ich wissen wollte! Ich muss das Buch auschecken. – Jake

+2

Ja, das Buch ist großartig, ich liebe es :) :) :) Danke für die rec. –

+5

Ich fand jedoch einen großen Unterschied: CreateItem erweitert Platzhalter, die ihm in Include übergeben werden, über eine Transformationsoperation wie , während eine ItemGroup-Deklaration sie nicht erweitert . –

7

Ich glaube nicht, dass die angenommene Antwort den Unterschied definiert hat.

Der Unterschied ist:

  • ItemGroup ausgewertet wird, wenn das MSBuild-Skript geladen wird.
  • CreateItem ausgewertet wird, wenn das Ziel dieses

ausgeführt wird, kann innerhalb des Skripts zu verschiedenen Werten der Artikel führen.

Nehmen Sie das Beispiel einer Aufgabe, die etwas mit all den Dateien tut, die "* .txt" in einem Verzeichnis entsprechen. Wenn Ihr MSBuild-Skript in Visual Studio geladen wird, befinden sich nur die Dateien, die beim Start von VS vorhanden waren, im Objekt, wenn Sie ItemGroup verwenden.

Wenn Sie CreateItem verwenden, wird nach allen * .txt-Dateien gesucht, wenn das Ziel ausgeführt wird.

+10

Der Fragesteller zeigt an, dass beide von einem Ziel aus aufgerufen werden. Aus Ihrer Antwort sieht es so aus, als ob Sie in vor MSBuild 3.5 Bedingungen denken. (Wenn ItemGroup nicht innerhalb eines Ziels platziert werden konnte). Wenn sich ItemGroup in einem Ziel befindet, ist es genauso dynamisch, als wäre es über CreateItem deklariert. (Das heißt, es wird ausgewertet, wenn das Ziel ausgeführt wird.) (Siehe Seite 51 von "In der Microsoft Build Engine: Verwenden von MSBuild und Team Foundation Build" als Referenz (oder probieren Sie es einfach aus)). – Vaccano

+0

@Vaccano: Eine Itemgroup ist innerhalb eines Targets "genauso dynamisch" mit der Ausnahme, die Johannes Rudolph in einem Kommentar zu der gewählten Antwort erwähnt - "CreateItem wird Wildcards erweitern, die ihm in Include über eine Transformationsoperation übergeben werden" ... while an ItemGroup-Deklaration wird nicht. – CyberMonk

17

CreateItem und CreateProperty sind in MSBuild 3.5 veraltet (obwohl natürlich immer weiter funktioniert). Es war ziemlich offensichtlich, dass wir die gleiche vertraute Syntax für ItemGroup und PropertyGroup brauchten, um innerhalb von Zielen zu arbeiten.

Aber ItemGroup in einem Ziel hat einige besondere zusätzliche Kräfte. Es kann Elemente ändern: Beispielsweise werden alle Elemente in der Ressourcenliste, die eine Metadaten mit dem Namen "Primär" mit dem Wert "Wahr" aufweisen, als "Wahr" hinzugefügt. nur wenn noch nicht vorhanden Metadaten kopieren:

Eine weitere magische Kraft: Sie können jetzt Elemente aus einer Liste entfernen.In diesem Beispiel werden alle Elemente aus der Ressourcenliste entfernen, die Metadatentyp mit Wert Bitmap haben:

<ItemGroup> 
    <Resources Condition=" '%(Type)'=='Bitmap' " Remove="@(Resources)"/> 
</ItemGroup> 

nur Diese magischen Kräfte derzeit innen arbeiten, nicht außerhalb.

Für vollständige Details dieses Materials, empfehle ich Sayed Hashimi's Buch auf MSBuild. Es ist leicht auf Amazon gefunden.

Dan - Msbuild-Team.

1

Als zusätzliche Information für andere, die hier übergeben werden: Die Build-Engine, die eine API zum Erstellen von MSBuild-Projekten enthält, unterstützt das Hinzufügen von ItemGroups zum neuen Weg zu einem Ziel nicht. Hier müssen Sie die altmodische Art benutzen.