Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
768 views
in Technique[技术] by (71.8m points)

msbuild - How to get all the metadata keys for any ItemGroup item?

Is there a way to get all the metadata keys associated with a given item?

I want to do something like the following.

Given:

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

Be able to determine that item1 has metadata available for key1, key2, and key3, and that item2 has metadata available for key4, without knowing what the names of those keys actually are.

In effect, I'm trying to use the metadata to specify attributes that I have no idea about, and then trying to figure out a way to check to see what attributes have been specified.

Put another way, I believe the metadata of each item is just a hash containing key/value pairs and I'm trying to figure out what all the keys are.

Anyone know how to do this with msbuild?

Thanks

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I ended up solving this using a custom inline task similar to the following:

<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}
", item);
              foreach (string parameter in item.MetadataNames)
              {
                  command.AppendFormat("  {0}={1}
", parameter, item.GetMetadata(parameter));
              }
              command.AppendFormat("
");
          }
          MetadataString = command.ToString();
      ]]>
    </Code>
  </Task>
</UsingTask>

Note that the above will also include all the default metadata that MSBuild automatically adds to every item in an itemgroup (like FullPath, RootDir, Filename, etc). In my implementation I added an extra check to ignore those metadata items that I didn't care about

Sample usage:

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

To see message output in Visual Studio's Output window, you may need to change your MSBuild output verbosity to at least Normal.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...