2013-07-04 20 views
6

C'è un modo per ottenere tutte le chiavi di metadata associate a un determinato articolo?Come ottenere tutte le chiavi di metadata per qualsiasi articolo ItemGroup?

Voglio fare qualcosa di simile al seguente.

Dato:

<ItemGroup> 
    <MyItems Include="item1"> 
     <key1>val1</key1> 
     <key2>val2</key2> 
     <key3>val3</key3> 
    </MyItems> 
    <MyItems Include="item2"> 
     <key4>val4</key4> 
    </MyItems> 
    </ItemGroup> 

Essere in grado di determinare che voce1 ha metadati disponibili per key1, chiave2, e key3, e che item2 ha metadati disponibili per key4, senza sapere quali sono i nomi di quelle chiavi sono in realtà.

In effetti, sto cercando di utilizzare i metadati per specificare gli attributi di cui non ho idea, e quindi cercando di capire un modo per verificare quali attributi sono stati specificati.

In altre parole, credo che i metadati di ogni elemento siano solo un hash contenente coppie chiave/valore e sto cercando di capire quali sono tutte le chiavi.

Qualcuno sa come farlo con msbuild?

Grazie

+2

Per quanto ne so, non esiste alcuna opzione per elencare i metadati di un elemento in MSBuild, ma è possibile scrivere un BuildTask personalizzato che esegue l'iterazione sui metadati riflessi e potrebbe elencarlo. – MikeR

+0

Sì, quella era la strada che ho finito per prendere –

risposta

14

ho finito per la soluzione di questo utilizzando un'attività in linea personalizzato simile al seguente:

<UsingTask 
    TaskName="GetMetadataTask" 
    TaskFactory="CodeTaskFactory" 
    AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" > 
    <ParameterGroup> 
    <MyItemGroup ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" /> 
    <MetadataString Output="true" /> 
    </ParameterGroup> 
    <Task> 
    <Using Namespace="System"/> 
    <Code Type="Fragment" Language="cs"> 
     <![CDATA[ 
      StringBuilder command = new StringBuilder(); 
      foreach (ITaskItem item in MyItemGroup) 
      { 
       command.AppendFormat("ItemName={0}\r\n", item); 
       foreach (string parameter in item.MetadataNames) 
       { 
        command.AppendFormat(" {0}={1}\r\n", parameter, item.GetMetadata(parameter)); 
       } 
       command.AppendFormat("\r\n"); 
      } 
      MetadataString = command.ToString(); 
     ]]> 
    </Code> 
    </Task> 
</UsingTask> 

Si noti che quanto sopra includerà anche tutti i metadati di default che MSBuild aggiunge automaticamente ad ogni elemento in un itemgroup (come FullPath, RootDir, Filename, ecc.). Nella mia implementazione ho aggiunto un controllo in più di ignorare gli elementi di metadati che non mi preoccupo

utilizzo Esempio:

<GetMetadataTask MyItemGroup="@(YourItemGroup)"> 
    <Output TaskParameter="MetadataString" PropertyName="YourMetadataString"/> 
</GetMetadataTask> 
<Message Text="$(YourMetadataString)" /> 

di vedere l'output messaggio nella finestra di output di Visual Studio, potrebbe essere necessario change your MSBuild output verbosity a almeno normale.

+0

Grazie, script fantastico! –

+2

Potresti mostrare un piccolo esempio di come utilizzare questa attività? – Ivan

+1

Grazie, è davvero d'aiuto! Ho aggiunto un codice di esempio per chiamarlo. – EM0