In working with TFS I just discovered the Well-Known Item Metadata (bad name in my opinion as I don't they they are really all that "Well-known") which can be used in MSBuild. One of these is %(RecursiveDir) .
From MSDN:
If the Include attribute contains the wildcard **, this metadata specifies the path to the file, beginning at the location of the wildcard. For more information on wildcards, see How to: Use Wildcards to Build All Files in a Directory.
This example has no RecursiveDir metadata, but if the following example was used to include this item, the item would contain a RecursiveDir value of MyProject\Source\.
<ItemGroup>
<MyItem Include="C:\**\Program.cs" />
</ItemGroup>
If the following example was used to include this item, the RecursiveDir value of the item would remain MyProject\Source\.
<ItemGroup>
<MyItem Include="C:\**\Source\Program.cs" />
</ItemGroup>
This gives a lot of flexibility when using MSBuild. It allows you to create a ItemGroup element which can include and exclude files in a directory recursively and then copy those files recursively to another directory!
This allowed me to do the following to copy the build out put of a web site (which naturally has a lot of sub-folders) easily up to the server.
<Target Name="AfterDropBuild" >
<Message Text="AfterDropBuild being fired" />
<ItemGroup>
<Compile Include="$(DropLocation)\$(BuildNumber)\Mixed Platforms\Release\_PublishedWebsites\User Interface\**\*.*"
Exclude="$(DropLocation)\$(BuildNumber)\Mixed Platforms\Release\_PublishedWebsites\User Interface\connectionStrings.config"/>
</ItemGroup>
<Copy SourceFiles="@(Compile)" DestinationFolder="\\ServerName\MyFolder\%(RecursiveDir)"></Copy>
<Message Text="Completed coping files" />
</Target>
MSBuild takes awhile to learn all the tricks, but the more tricks I learn the more I like it.
Comments