如何执行不覆盖现有文件的MSBuild复制命令?

6

查看复制任务的文档,我没有看到明显的方法可以在目标位置复制文件时不覆盖现有文件。我只想复制新文件。

我目前的做法:

<ItemGroup> 
  <Packages Include=".nuget-publish\*.*"  />
</ItemGroup>

<Copy SourceFiles="@(Packages)" DestinationFolder="\\server\nuget\packages\" />

啊!通过“我只想要更新的文件”这句话,我以为我们在看日期戳,但你是想只在目标文件不存在时才进行复制? - Nicodemeus
3个回答

8

条件属性可以用于过滤源文件:

<Copy SourceFiles="@(SourceFiles)" DestinationFiles="$(DestinationPath)%(RecursiveDir)%(Filename)%(Extension)" Condition="!Exists('$(DestinationPath)%(RecursiveDir)%(Filename)%(Extension)')" />

6

在您的链接中有一个属性“SkipUnchangedFiles”。将其添加到复制任务中,并将其设置为“true”。

<Copy SourceFiles="@(Packages)" DestinationFolder="\\server\nuget\packages\" SkipUnchangedFiles="true" />  

编辑: 我创建了一个带有以下内容的示例项目。

<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup> 
        <ExistingPackages Include="dest\*.*" />
        <Packages Include="src\*.*" Exclude="@(ExistingPackages -> 'src\%(FileName)%(Extension)')" />
    </ItemGroup>
    <Target Name="Build">
        <Message Text="PackagesToCopy @(Packages)" Importance="high" />
    </Target>
</Project>

文件夹 + 文件分类法是:

src\
    doc1.txt
    doc2.txt
    doc3.txt
    doc4.txt
    doc5.txt
    doc6.txt
dest\
    doc2.txt
    doc4.txt
    doc6.txt
CopyNew.proj

当我运行msbuild.exe CopyNew.proj时,会得到以下输出:
Build:
  PackagesToCopy src\doc1.txt;src\doc3.txt;src\doc5.txt

现在@(Packages)不再包含目标文件夹中已存在的文件!


1
不是同一件事。文件可能已经在源中更改,但不应再被覆盖。我不想用更改覆盖文件。 - Jim Bolla

-1

SkipUnchangedFiles="true"选项仅在源文件新于目标文件时才复制文件。

有时,您需要仅复制不存在于目标文件夹中的文件,而不进行任何文件日期比较。在这种情况下,您可以在复制任务上使用条件:

<Copy SourceFiles="%(Packages.Identity)" DestinationFolder="$(TargetDir)" SkipUnchangedFiles="true" Condition="!(Exists(@(Packages->'$(TargetDir)%(Filename)%(Extension)')))" />

1
请注意,SkipUnchangedFiles将跳过一个文件“如果它们具有相同的大小和最后修改时间”(根据文档)。这与“仅在源文件新于目标文件时复制文件”不同。 - RB.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接