问题
I want to pass a semi-colon separated list of strings.
Each string represents a file name.
<PropertyGroup>
<FileNames>Newtonsoft.Json;Reactive</FileNames>
<PathToOutput>C:/</PathToOutput>
</PropertyGroup>
Now I want to create an item group which should give me all the files in particular folder excluding list of Filename, something like:
<ItemGroup>
<ReleaseFiles Include="$(PathToOutput)\**\*.*" Exclude="%(identity)-> identity.contains(%FileNames)"/>
</ItemGroup>
How do I iterate through current folder's files and match each ones name if it contains any one filename in Filenames variable.
回答1:
Pretty sure this is a duplicate but I cannot find it at the moment so here it goes:
- turning a semicolon-seperated property into an item is just a matter of using
Include=$(Property)
Exclude
only works if you have a list of exact matches, but you need more arbitrary filtering here so you'll needCondition
- join the two ItemGroups together like a cross-product, by making those FileNames metadata of the ReleaseFiles item. Then you can iterate over each item in ReleaseFiles and have access to the FileNames at the same time
Contains
is a property function (well, or a System::String method) so won't work as such on metadata, hence we turn metadata into a string first
In code:
<PropertyGroup>
<FileNames>Newtonsoft.Json;Reactive</FileNames>
<PathToOutput>C:/</PathToOutput>
</PropertyGroup>
<Target Name="FilterBasedCommaSeperatedProperty">
<ItemGroup>
<!-- property -> item -->
<Excl Include="$(FileNames)"/>
<!-- list all and add metadata list -->
<AllReleaseFiles Include="$(PathToOutput)\**\*.*">
<Excl>%(Excl.Identity)</Excl>
</AllReleaseFiles >
<!-- filter to get list of files we don't want -->
<FilesToExclude Include="@(AllReleaseFiles)"
Condition="$([System.String]::Copy('%(FileName)').Contains('%(Excl)'))"/>
<!-- all but the ones to exclude -->
<ReleaseFiles Include="@(AllReleaseFiles)" Exclude="@(FilesToExclude)"/>
</ItemGroup>
<Message Text="%(ReleaseFiles.Identity)" />
</Target>
回答2:
Use the standard way to exclude files files from an item group by using the Exclude attribute and referencing another item group. It'll be much easier to understand.
Example:
<PropertyGroup>
<PathToOutput>C:/</PathToOutput>
</PropertyGroup>
<ItemGroup>
<FilesToExclude Include="$(PathToOutput)\**\Newtonsoft.Json" />
<FilesToExclude Include="$(PathToOutput)\**\Reactive" />
<ReleaseFiles Include="$(PathToOutput)\**\*.*" Exclude="@(FilesToExclude)"/>
</ItemGroup>
来源:https://stackoverflow.com/questions/37860576/msbuild-create-itemgroup-from-property-group