I have a situation where I need to copy a few specific files in a MSBuild script, but they may or may not exist. If they don't exist it's fine, I don't need them then. But the standard <copy>
task throws an error if it cannot find each and every item in the list...
Asked
Active
Viewed 2.0k times
30

Vilx-
- 104,512
- 87
- 279
- 422
3 Answers
57
Use the Exists condition on Copy task.
<CreateItem Include="*.xml">
<Output ItemName="ItemsThatNeedToBeCopied" TaskParameter="Include"/>
</CreateItem>
<Copy SourceFiles="@(ItemsThatNeedToBeCopied)"
DestinationFolder="$(OutputDir)"
Condition="Exists('%(RootDir)%(Directory)%(Filename)%(Extension)')"/>

Julien Hoarau
- 48,964
- 20
- 128
- 117
-
1Thanx! I had forgotten about these! :) – Vilx- Feb 04 '09 at 15:51
-
9It is also worth mentioning that instead of `%(RootDir)%(Directory)%(Filename)%(Extension)`, one can simply use `%(FullPath)` (see http://msdn.microsoft.com/en-us/library/ms171476.aspx) – AASoft Sep 14 '13 at 23:23
-
Mind that when you are using transform when providing `SourceFiles`, you need to provide the exact same transform in `Condition` – patryk Jun 16 '16 at 14:30
9
The easiest would be to use the ContinueOnError flag http://msdn.microsoft.com/en-us/library/7z253716.aspx
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<MySourceFiles Include="a.cs;b.cs;c.cs"/>
</ItemGroup>
<Target Name="CopyFiles">
<Copy
SourceFiles="@(MySourceFiles)"
DestinationFolder="c:\MyProject\Destination"
ContinueOnError="true"
/>
</Target>
</Project>
But if something else is wrong you will not notice it. So the condition exist from madgnome's answer would be better.

KeesDijk
- 2,299
- 1
- 24
- 37
1
It looks like you can mark MySourceFiles as SkipUnchangedFiles="true" and it won't copy the files if they already exist.

kevindaub
- 3,293
- 6
- 35
- 46
-
It won't copy the files only if they have the same size and same modification date, otherwise files still will be overridden. – Grengas Sep 15 '21 at 13:23