msbuildmetadataitemgroup

MsBuild: Flattening of nested ItemGroup with variable number of metadata


Assume the following ItemGroup structure:

<ItemGroup>
  <BinaryFiles Include="C:\">
    <Binary>a.dll</Binary>
    <Binary>b.dll</Binary>
  </BinaryFiles>
  <BinaryFiles Include="D:\">
    <Binary>my.ddl</Binary>
  </BinaryFiles>
</ItemGroup>

I need to flatten this to a string like this:

C:\a.dll;C:\b.dll;D:\my.dll

How would I do that? If it's not possible, is there a better way to do it?


Solution

  • A metadata value can have only one value. Multiple definitions and updates will override the value, so the "C:\" item will only have b.dll as Binary metadata.

    If there is only one element in the metadata then @(BinaryFiles->'%(Identity)%(Binary)') would yield the result you wanted.

    However, since you are using file based logic, you are better off using a BinaryFiles item for each item:

    <BinaryFiles Include="C:\*.dll" />
    <BinaryFiles Include="D:\*.dll" />
    

    This will scan for all the dll files. You can even use D:\**\*.dll to scan recursively. Then you can use @(BinaryFiles->'%(FullPath') to get the list of all absolute paths.