如何获取任何ItemGroup项的所有元数据键?

Zai*_*zvi 9 msbuild msbuild-4.0 itemgroup

有没有办法获得与给定项目关联的所有元数据键?

我想做类似以下的事情.

鉴于:

  <ItemGroup>
    <MyItems Include="item1">
      <key1>val1</key1>
      <key2>val2</key2>
      <key3>val3</key3>
    </MyItems>
    <MyItems Include="item2">
      <key4>val4</key4>
    </MyItems>
  </ItemGroup>
Run Code Online (Sandbox Code Playgroud)

能够确定item1具有可用于key1,key2和key3的元数据,并且item2具有可用于key4的元数据,而不知道这些键的名称实际上是什么.

实际上,我正在尝试使用元数据来指定我不知道的属性,然后尝试找出一种方法来检查以查看已指定的属性.

换句话说,我相信每个项目的元数据只是一个包含键/值对的哈希,我试图找出所有键的内容.

任何人都知道如何使用msbuild做到这一点?

谢谢

Zai*_*zvi 20

我最终使用类似于以下内容的自定义内联任务来解决此问题:

<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>
Run Code Online (Sandbox Code Playgroud)

请注意,上面还将包括MSBuild自动添加到项目组中每个项目的所有默认元数据(如FullPath,RootDir,Filename等).在我的实现中,我添加了一个额外的检查,以忽略那些我不关心的元数据项

样品用法:

<GetMetadataTask MyItemGroup="@(YourItemGroup)">
  <Output TaskParameter="MetadataString" PropertyName="YourMetadataString"/>
</GetMetadataTask>
<Message Text="$(YourMetadataString)" />
Run Code Online (Sandbox Code Playgroud)

要在Visual Studio的"输出"窗口中查看消息输出,您可能需要将MSBuild输出详细程度更改为至少"正常".

  • 你能否举一个如何使用这个任务的小例子? (2认同)
  • @EM,我去找了你的编辑,被拒绝了(错误地,IMO).这里是@EM试图帮助的人:`<GetMetadataTask MyItemGroup ="@(YourItemGroup)"> <输出TaskParameter ="MetadataString"PropertyName ="YourMetadataString"/> </ GetMetadataTask>` (2认同)
  • dotnet core 不支持 CodeTaskFactory,但是通过进行一些更改,这仍然适用于新的 [RoslynCodeTaskFactory](https://github.com/microsoft/msbuild/pull/3175): `TaskFactory="RoslynCodeTaskFactory" AssemblyFile= “$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll”` (2认同)