If the files to copy are being generated on the fly by the build process you'll have to use the <CreateItem> task to build the item list as part of your compile target. Then the copy will work fine. See http://blogs.msdn.com/msbuild/archive/2005/10/04/476725.aspx for more details.
Thanks for the posts, guys. I think you're on to something here. here's what my build file looks like: ... <ItemGroup> <Binaries Include="$(RootFolder)\bin\*.*"/> <Charts Include="$(RootFolder)\ch\*.*"/> <Scripts Include="$(DBScriptPath)\*.*"/> </ItemGroup>
My ItemGroup to list the files to copy is evaluated before the build task has produced the assemblies so if I have a clean version, the assemblies are not included.
When the copy runs the first time the assemblies are not included. Not so hot if I clean each time!
Is it because the target is up to date The task will skip in that case if you have Inputs & Outputs on the target, or you have set SkipUnchangedFiles="true".
A small project that demonstrates the problem would help us.
Here is a sample: <CreateItem Include="bin\debug\**\Data*.dll;bin\debug\**\Data*.exe;"> <Output TaskParameter="Include" ItemName="TestAssemblies"/> </CreateItem> This would create an item called TestAssemblies that contained all the Data*.dll and Data*.exe files in sub-folders of the bin\debug directory. You could then copy the files using @(TestAssemblies) as the SourceFiles
I haven't encountered any problems using the Copy task as you are illustrating. Maybe it is something besides the Copy task One possibliity that would work on & off would be if you are copying based on an Item. Items are evaluated at the begining of the build, so if you have an item like: <ItemGroup> <CopyFiles Include="**\*.dll"/> </ItemGroup> The CopyFiles will be pouplated at the begining of the build, when you may be expecting it to be populated at the time it is referenced. So if you are creating new .dll files they will not be picked up by the Include for CopyFiles. If this is what you are trying to do use the CreateItem task to dynamically create the item right before you try to copy the files. Sorry if this is not the issue.
MSBuild Copy Task works intermittently
parkfield
Thanks for the tip, I'll keep it in mind for my test assemblies.
For the recursive copy of my output, I'll stick with XCopy; Its simple and easily understood by others.
pascalh
Andrew,
If the files to copy are being generated on the fly by the build process you'll have to use the <CreateItem> task to build the item list as part of your compile target. Then the copy will work fine. See http://blogs.msdn.com/msbuild/archive/2005/10/04/476725.aspx for more details.
Neil
k a u s h i
Thanks for the posts, guys. I think you're on to something here. here's what my build file looks like:
...
<ItemGroup>
<Binaries Include="$(RootFolder)\bin\*.*"/>
<Charts Include="$(RootFolder)\ch\*.*"/>
<Scripts Include="$(DBScriptPath)\*.*"/>
</ItemGroup>
<Target Name="Build">
<Message Text="Cleaning out previous build files" />
<RemoveDir Directories="$(RootFolder)\bin" />
<RemoveDir Directories="$(RootFolder)\ch" />
<RemoveDir Directories="$(DBScriptPath)" />
<RemoveDir Directories="$(WorkingFolder)" />
<MakeDir Directories="$(RootFolder)\ch" />
<MakeDir Directories="$(RootFolder)\bin" />
<MakeDir Directories="$(WorkingFolder)" />
<MakeDir Directories="$(DBScriptPath)" />
...
<Message Text="Creating output folders" />
<MakeDir Directories="$(OutputFolder)\$(ProductName) $(VersionName) $(VersionNumber)" />
<MakeDir Directories="$(OutputFolder)\$(ProductName) $(VersionName) $(VersionNumber)\bin" />
<MakeDir Directories="$(OutputFolder)\$(ProductName) $(VersionName) $(VersionNumber)\DBScripts" />
<MakeDir Directories="$(OutputFolder)\$(ProductName) $(VersionName) $(VersionNumber)\ch" />
<Message Text="Moving Binaries to output folder" />
<Copy
SourceFiles="@(Binaries)"
DestinationFiles="@(Binaries->'$(OutputFolder)\$(ProductName) $(VersionName) $(VersionNumber)\bin\%(RecursiveDir)%(Filename)%(Extension)')"/>
<Message Text="Moving Charts to output folder" />
<Copy
SourceFiles="@(Charts)"
DestinationFiles="@(Charts->'$(OutputFolder)\$(ProductName) $(VersionName) $(VersionNumber)\ch\%(RecursiveDir)%(Filename)%(Extension)')"/>
<Message Text="Moving Database Scripts to output folder" />
<Copy
SourceFiles="@(Scripts)"
DestinationFiles="@(Scripts->'$(OutputFolder)\$(ProductName) $(VersionName) $(VersionNumber)\DBScripts\%(RecursiveDir)%(Filename)%(Extension)')"/>
I bet it has to do with the fact that I'm using the item instead of creating them on the fly. Have a quick sample on how to do that
Angelo
John.Doe
My ItemGroup to list the files to copy is evaluated before the build task has produced the assemblies so if I have a clean version, the assemblies are not included.
When the copy runs the first time the assemblies are not included. Not so hot if I clean each time!
XCOPY works just fine.
<
Exec Command='xcopy /E <from> <to>' />David Hatch
A small project that demonstrates the problem would help us.
Dan
TimLa
<CreateItem Include="bin\debug\**\Data*.dll;bin\debug\**\Data*.exe;">
<Output TaskParameter="Include" ItemName="TestAssemblies"/>
</CreateItem>
This would create an item called TestAssemblies that contained all the Data*.dll and Data*.exe files in sub-folders of the bin\debug directory.
You could then copy the files using @(TestAssemblies) as the SourceFiles
Hope this helps,
Sayed Ibrahim Hashimi
kula
<ItemGroup>
<CopyFiles Include="**\*.dll"/>
</ItemGroup>
The CopyFiles will be pouplated at the begining of the build, when you may be expecting it to be populated at the time it is referenced. So if you are creating new .dll files they will not be picked up by the Include for CopyFiles. If this is what you are trying to do use the CreateItem task to dynamically create the item right before you try to copy the files. Sorry if this is not the issue.
Sayed Ibrahim Hashimi