trying to copy a whole folder, but when i do this:
Copying files can be done with the following code snippet which handles antivirus programs and subdirectories
<ItemGroup>
<SomeAppStuff Include="$(SolutionDir)\ProjectXXX\bins\**\*.*" />
</ItemGroup>
<Copy
SourceFiles="@(SomeAppStaff)"
DestinationFolder="$(OutputPath)\%(RecursiveDir)"
SkipUnchangedFiles="true"
OverwriteReadOnlyFiles="true"
Retries="3"
RetryDelayMilliseconds="300"/>
Specifying $(OutputPath)\%(RecursiveDir)
will ask Copy task to respect subfolders, so it will place subfolders of source directory to subfolders of target directories.
SkipUnchangedFiles
will increase build speed on computers with enough memory, because Windows optimizes IO for frequently used files when there's enough RAM.
Retries
and RetryDelayMilliseconds
handles issues related
a) Compressed NTFS file system, when builds fails in seldom cases b) Antivirus Software with SSD drives.
Succeeded to accomplish this task like this
<Target Name="AfterBuild">
<ItemGroup>
<SomeDir Include="$(SolutionDir)\SomeOtherProject\SomeDir\**\*" />
</ItemGroup>
<Copy
SourceFiles="@(SomeDir)"
DestinationFiles="@(SomeDir->'$(OutDir)\SomeDir\%(RecursiveDir)%(Filename)%(Extension)')"
SkipUnchangedFiles="true"
OverwriteReadOnlyFiles="true"
Retries="3"
RetryDelayMilliseconds="300" />
Specify your ItemGroup for SourceFiles explicitly.
<ItemGroup>
<_CopyItems Include="$(TargetDir)\*.*" />
</ItemGroup>
<Copy
SourceFiles="@(_CopyItems)"
DestinationFolder="$(BuildOutput)\SomeDir"
/>
Note that _CopyItems is an item type, so it's referenced using '@' symbol rather than '$'.
Looking at the MSDN documentation, I believe the SourceFiles parameter requires an ITaskItem[] value. See MSDN MSBuild Copy Task
The last example on the above link is to do a recursive copy from one directory to another, maintaining the folder structure.
If you put the folder in the root of your c# project then you can simple put this in your csproj.
<ItemGroup>
<None Update="FolderToCopy\**\*.*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
I have only tested in the 2017 version of csproj, but I assume it's backwards compatible. Could be wrong on that though
The best solution for me was to use the magic XCOPY
as I had to copy all files and sub directories
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<PropertyGroup>
<FilesSource>$(ProjectDir)\lib</FilesSource>
<FilesDestination Condition=" '$(SolutionName)' == 'any name a' ">$(ProjectDir)\..\..\Something\lib</FilesDestination>
<FilesDestination Condition=" '$(SolutionName)' == 'the top solution name' ">$(SolutionDir)\Something\lib</FilesDestination>
</PropertyGroup>
<Error Condition=" '$(FilesDestination)' == '' " Text="Lib not delivered. To disable this message, remove the 'Target' tag from the project file" />
<Exec Command="RD /S /Q "$(FilesDestination)"" />
<Exec Command="XCOPY "$(FilesSource)" "$(FilesDestination)" /E /I /H /R /K /Y" />
<Exec Command="RD /S /Q "$(FilesSource)"" />
</Target>
This build event is fired once build succeed, it cleans the FilesDestination
folder then it copies all files with directory structure from FilesSource
to FilesDestination
and then it delete the FilesSource
folder to keep everything "bien propre" :)
NOTE
For FilesDestination
, make sure you use the Condition attribute or remove it to have the copy process to its end