Why MSBuild is not copied, as I would expect

I need to script my assembly. I use MSBUILD because of its integration with VS.net. I am trying to copy some files from the build environment to the deployment folder. I am using the MSBuild copy task. But instead of copying the directory tree, as you would expect. it copies all contents to one folder. I repeat all the files from the directory tree in one folder. I need to copy a tree of folders and directories to the destination folder. Is something missing?

Here are some parts of my build script:

<PropertyGroup> <TargetFrameworkVersion>v2.0</TargetFrameworkVersion> <Source>outputfolder</Source> <DestEnv>x</DestEnv> <DeployPath>\\networkpath\$(DestEnv)</DeployPath> </PropertyGroup> <ItemGroup> <TargetDir Include="$(DeployPath)\**\*" Exclude="**\web.config"></TargetDir> <SourceDir Include="$(Source)\**\*" /> </ItemGroup> <Target Name="Clean" > <!-- clean detail ... --> </Target> <Target Name="migrate" DependsOnTargets="Clean"> <Copy DestinationFolder="$(DeployPath)" SourceFiles="@(SourceDir)" /> </Target> 
+7
msbuild
source share
4 answers

Just the stone that we discovered when we debugged MSBuild problems when copying:

http://blog.scrappydog.com/2008/06/subtle-msbuild-bug-feature.html

Group elements are analyzed to target values, so any target objects that create new files (for example, compilation!) Will not be picked up if the ItemGroup element is further referred to by the script.

Eric Bowen also describes the work for this "function", the CreateItem task:

 <Target Name="Copy" > <CreateItem Include="..\Source\**\bin\**\*.exe" Exclude="..\Source\**\bin\**\*.vshost.exe"> <Output TaskParameter="Include" ItemName="CompileOutput" /> </CreateItem> <Copy SourceFiles="@(CompileOutput)" DestinationFolder="$(OutputDirectory)"></Copy> </Target> 

Praises him a lot!

+13
source share

When you specify the DestinationFolder task to copy, it takes all the items from the SourceFiles collection and copies them to the DestinationFolder. This is expected since the Copy task does not allow to determine which part of each element path must be replaced by a DestinationFolder in order to preserve the tree structure. For example, if your SourceDir collection is defined as follows:

 <ItemGroup> <SourceDir Include="$(Source)\**\*" /> <SourceDir Include="E:\ExternalDependencies\**\*" /> <SourceDir Include="\\sharedlibraries\gdiplus\*.h" /> </ItemGroup> 

What do you expect from the destination folder tree?

To save the tree, you need to perform an identity transformation and create one destination for each element in the SourceFiles collection. Here is an example:

 <Copy SourceFiles="@(Compile)" DestinationFiles="@(Compile->'$(DropPath)%(Identity)')" /> 

The Copy task takes each element in the SourceFiles collection and transforms its path, replacing the part before ** in the source specification with $ (DropPath).

It can be argued that the DestinationFolder property should have been written as a shortcut to the following conversion:

 <Copy SourceFiles="@(Compile)" DestinationFiles="@(Compile->'$(DestinationFolder)%(Identity)')" /> 

Alas, this will prevent a deep copy script that you are trying to avoid, but other people can use them in the build process.

+12
source share

A very simple example that copies directory contents and structure recursively:

 <Copy SourceFiles="@(Compile)" DestinationFolder="c:\foocopy\%(Compile.RecursiveDir)"></Copy> 

@ (Compile) is an ItemGroup of all the files you want to copy. Maybe something like:

  <ItemGroup> <Compile Include=".\**\*.dll" /> </ItemGroup> 

The Copy task will copy all files to c: \ foocopy, like xcopy.

+5
source share

I found an example in one of the examples on MSDN I don't understand this, but will leave an example for my colleague travlers here in stackoverflow. Here is a fixed version of the migrating target from above:

 <Target Name="migrate" DependsOnTargets="Clean"> <Copy DestinationFiles="@(SourceDir->'$(DeployPath)\%(RecursiveDir)%(Filename)%(Extension)')" SourceFiles="@(SourceDir)" /> </Target> 

If someone really understands this example, please explain. Good luck

+4
source share

All Articles