How To: Create Item Groups on the Fly

Here's another good question from our internal Visual Studio build conversion alias:

Suppose I have a target that produces an unpredictable number of output files and doesn’t use a Task Output to return that list to me. (Think compiling a .SLN file and it produces a set of XXX.Test.dll assemblies that I need for a later target.) When I use an ItemGroup to find this:

$(MSBuildProjectDirectory)\**\bin\$(Configuration)\*.Tests.dll

It works on the second run of the msbuild file, but the first time it is an empty item group. I’m guessing that this is because the itemgroup is resolved when the script is loaded and not when it is referenced from my later target. How do I fix this?

The original poster is correct: when MSBuild is launched the item groups are evaluated before targets are run. You can, however, create item groups on the fly using the <CreateItem> task. In the above case you'd do something like this as part of a target:

<CreateItem Include="$(MSBuildProjectDirectory)\**\bin\$(Configuration)\*.Tests.dll">
   <Output TaskParameter="Include" ItemName="PreviousResultsFiles"/>
</CreateItem>

After that task executes you'll wind up with a new item group called PreviousResultsFiles. As always, complete documentation on the CreateItem task is available at MSDN.

[ Author: Neil Enns ]