Suppose you want to use CreateItem to build a string containing a pattern, based on the value of a property being passed to your Target (say, to make an OpenCover Filter group).
If the Include attribute value includes an asterisk (even if escaped as hex) then a pattern match is attempted against the filesystem, and you end up with nothing in the group.
After several hours of messing about, I came up with a solution building the pattern with the word STAR instead of an asterisk, and using an inline C# Target to create a TaskItem
with the correct text.
Here is the result, in a .proj file at the solution level and using the NuGet packages for OpenCover, NUnit.Runners and ReportGenerator.
<?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Clean" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> <PropertyGroup> <OpenCoverVersion>4.5.1403</OpenCoverVersion> <NUnitVersion>2.6.2</NUnitVersion> <ReportGeneratorVersion>1.8.0.0</ReportGeneratorVersion> </PropertyGroup> <ItemGroup> <TestedNamespace Include="MyCode"> <TestsNamespace>MyCode.Tests</TestsNamespace> </TestedNamespace> <TestedNamespace Include="MyWebStuff"> <TestsNamespace>MyWebStuff.Tests</TestsNamespace> </TestedNamespace> <ReportFiles Include="@(TestedNamespace->'OpenCover\%(TestsNamespace).opencover.xml')"/> </ItemGroup> <PropertyGroup> <Configuration Condition="'$(Configuration)' == ''">Release</Configuration> <OpenCoverPath>$(MSBuildProjectDirectory)\packages\OpenCover.$(OpenCoverVersion)</OpenCoverPath> <OpenCoverMSBuildTasksPath>$(OpenCoverPath)\MSBuild</OpenCoverMSBuildTasksPath> <OpenCoverPath>$(MSBuildProjectDirectory)\packages\OpenCover.$(OpenCoverVersion)</OpenCoverPath> <OpenCoverMSBuildTasksPath>$(OpenCoverPath)\MSBuild</OpenCoverMSBuildTasksPath> <NUnitRunner>$(MSBuildProjectDirectory)\packages\NUnit.Runners.$(NUnitVersion)\tools\nunit-console-x86.exe</NUnitRunner> <ReportGenerator>$(MSBuildProjectDirectory)\packages\ReportGenerator.$(ReportGeneratorVersion)\ReportGenerator.exe</ReportGenerator> </PropertyGroup> <Import Project="$(OpenCoverMSBuildTasksPath)\OpenCover.targets"/> <UsingTask AssemblyFile="$(ReportGenerator)" TaskName="ReportGenerator"/> <UsingTask TaskName="TurnSTARintoActualStar" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll"> <ParameterGroup> <Input ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" /> <Result ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true" /> </ParameterGroup> <Task> <Code Type="Fragment" Language="cs"> <![CDATA[ if (Input.Length > 0) { Result = new TaskItem[Input.Length]; for (int i = 0; i < Input.Length; i++) { ITaskItem item = Input[i]; Result[i] = new TaskItem(item.GetMetadata("Identity").Replace("STAR", "*")); } } ]]> </Code> </Task> </UsingTask> <Target Name="Clean"> <RemoveDir Directories="OpenCover" /> <CallTarget Targets="Report"/> </Target> <Target Name="Report" DependsOnTargets="Build"> <ReportGenerator TargetDirectory="OpenCover\Report" ReportTypes="Html" ReportFiles="@(ReportFiles)" /> </Target> <Target Name="Build" Inputs="@(TestedNamespace)" Outputs="OpenCover\%(TestsNamespace).opencover.xml"> <MakeDir Directories="OpenCover" /> <CreateItem Include="+[%(TestedNamespace.Identity)STAR]STAR;-[%(TestedNamespace.TestsNamespace)]STAR;-[%(TestedNamespace.Identity)STAR]%(TestedNamespace.Identity).Properties.STAR"> <Output TaskParameter="Include" ItemName="SafeFilters" /> </CreateItem> <CreateItem Include="$(MSBuildProjectDirectory)\%(TestedNamespace.TestsNamespace)\bin\$(Configuration)\%(TestedNamespace.TestsNamespace).dll"> <Output TaskParameter="Include" PropertyName="TestsAssemblyPath" /> </CreateItem> <CreateItem Include='"$(TestsAssemblyPath)" /noshadow /xml:"OpenCover\%(TestedNamespace.TestsNamespace).nunit.xml"'> <Output TaskParameter="Include" PropertyName="NUnitArgs" /> </CreateItem> <CreateItem Include="@(TestedNamespace->'OpenCover\%(TestsNamespace).opencover.xml')"> <Output TaskParameter="Include" PropertyName="OpenCoverXml" /> </CreateItem> <TurnSTARintoActualStar Input="@(SafeFilters)"> <Output ItemName="Filters" TaskParameter="Result" /> </TurnSTARintoActualStar> <OpenCover ToolPath="$(OpenCoverPath)" Register="True" Target="$(NUnitRunner)" TargetArgs='$(NUnitArgs)' Output="$(OpenCoverXml)" CoverByTest="$(TestsAssemblyPath)" Filter="@(Filters)"/> </Target> </Project>