ItemGroup with custom metadata regarding files

I am trying to create a group of items in the Files task with a metadata attribute called TargetPath populated with the relative path to the file.

Example:
For these paths:

D: \ Test \ Blah.exe
D: \ Test \ Config \ fun.config
D: \ Test \ en-US \ my.resources.dll

The output should be:

File Target = Blah.exe
File Target = Config \ fun.config
File Target = en-US \ my.resources.dll

Here is my best attempt ... hope this makes my question clearer:

<ItemGroup> <Files Include="d:\test\**\*" > <TargetPath>%(RecursiveDir)%(Filename)%(Extension)</TargetPath> </Files> </ItemGroup> <Message Text="File Target = @(Files->'%(TargetPath)')"/> 

I would like the TargetPath to populate correctly ... currently it seems empty or empty. Does anyone know what I am missing?

Edit:

Yes, I understand that I can do this:

 <Message Text="File Target = @(Files->'%(RecursiveDir)%(Filename)%(Extension)')"/> 

However, I am creating this ItemGroup to use the ResolveManifestFiles MSBuild task, which requires me to create a TaskItem with the TargetPath metadata attribute in order to be able to customize this value.

+7
msbuild
source share
3 answers

You are trying to assign dynamic metadata to an element group before creating it. In your example, there is no need to create custom metadata, since this information is already part of the known metadata, so you can simply do:

 <ItemGroup> <Files Include="d:\test\**\*" ></Files> </ItemGroup> <Message Text="File Target = @(Files->'%(RecursiveDir)%(Filename)%(Extension)')"/> 

Or:

 <Message Text="File Target = %(Files.RecursiveDir)%(Files.Filename)%(Files.Extension)"/> 

EDIT:

This example uses CreateItem to dynamically update a group of elements:

 <ItemGroup> <Files Include="d:\test\**\*" ></Files> </ItemGroup> <CreateItem Include="@(Files)" AdditionalMetadata="TargetPath=%(RecursiveDir)%(Filename)%(Extension)"> <Output TaskParameter="Include" ItemName="Files"/> </CreateItem> 
+6
source share

Modern MSBuild does not require CreateTask (since .NET 3.5).

You can do it as follows:

 <ItemGroup> <Files Include="d:\test\**\*" /> <FilesWithMetadata Include="%(Files.Identity)" > <TargetPath>%(RecursiveDir)%(Filename)%(Extension)</TargetPath> </FilesWithMetadata> </ItemGroup> 
+2
source share

I like the CreateItem method to use as follows:

  <ItemGroup> <Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <HintPath>..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll</HintPath> <Private>True</Private> </Reference> ... </ItemGroup> <CreateItem Include="@(Reference)" Condition="'%(Reference.Private)' == 'True'" AdditionalMetadata="TargetPath=$([System.IO.Path]::GetFileName(%(Reference.HintPath)))"> <Output TaskParameter="Include" ItemName="DLLFiles"/> </CreateItem> <Message Text="HintPaths: &quot;@(DLLFiles->'$(OutputPath)%(TargetPath)')&quot;" Importance="high" /> 

I use Transforms to just get just the file name.

Output:

HintPaths: "Bin \ Release \ log4net.dll; Bin \ Release \ Newtonsoft.Json.dll; Bin \ Release \ RabbitMQ.Client.dll; Bin \ Release \ ReflectSoftware.Insight.dll"

0
source share

All Articles