Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expand MSBuild Properties containing wildcard into Items

Tags:

c#

.net

msbuild

I am trying to write MSBuild script that will perform some action (eg. print its path) on an arbitrary files (specified as a property on a command line) in some predefined directory (F:\Files).

Given the following directory structure

F:\Files\TextFile.txt
F:\Files\Subdir1\ImageFile.bmp
F:\Files\Subdir1\SubSubdir\ImageFile2.bmp
F:\Files\Subdir1\SubSubdir\TextFile2.txt

And MSBuild Script

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="PrintNames" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <TargetDir>F:\Files</TargetDir>
    </PropertyGroup>

    <ItemGroup>
        <Files Include="$(TargetDir)\$(InputFiles)"/>
    </ItemGroup>

    <Target Name="PrintNames">
        <Message Text="Files: @(Files, ', ')" />
    </Target>
</Project>

running the script with InputFiles set to "**\*.bmp;**\*.txt" works fine only for bmp files. Txt files are taken from the current working directory, not from "F:\Files"

like image 872
Maciej Wozniak Avatar asked Jan 29 '12 18:01

Maciej Wozniak


1 Answers

There are two problems that you have to solve:

  1. $(InputFiles) is specifed as a scalar property, but you want to interprete it as an array
  2. $(InputFiles) contains wildcards you want to expand after you do transformation on the list of patterns in $(InputFiles).

It is easy to solve either of two problems separately, but combination of the two is actually tricky. I have one possible solution, and it works, but the downside is you have to encode '*' characters in your pattern definition.

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" DefaultTargets="PrintNames" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
  <PropertyGroup> 
    <TargetDir>c:\temp\MyContent</TargetDir> 
    <InputFilesRelativeEsc>%2A%2A\%2A.bmp;%2A%2A\%2A.txt</InputFilesRelativeEsc>
  </PropertyGroup> 

  <Target Name="PrintNames"> 
    <ItemGroup>
        <_TempGroup Include="$(InputFilesRelativeEsc)" />
    </ItemGroup>

    <CreateItem Include="@(_TempGroup->'$(TargetDir)\%(Identity)')"> 
        <Output TaskParameter="Include" ItemName="_EvaluatedGroup" /> 
    </CreateItem> 
    <Message Text="_EvaluatedGroup: %(_EvaluatedGroup.FullPath)" />

  </Target> 
</Project> 

It works as follows. Property InputFilesRelativeEsc is a list of relative file patterns. Notice wildcard characters are encoded (%2A is a hex code for asterisk). Since the wildcards encoded, the group _TempGroup does not attempt to search for and extract list of files while you Include this patterns into this group. Now _TempGroup is a group which consists of two elements: **\*.bmp and **\*.txt. Now that you have a real group you can transform it. The only complication is that the normal MSBuild mechanism of running transform does not expand wildcards. You have to use older CreateItem task. The CreateItem task is actually declared deprecated by MSBuild team, but it still works.

like image 76
seva titov Avatar answered Nov 15 '22 04:11

seva titov