make an MSBuild Copy Task only copy if the source is newer regardless of size

Brannon picture Brannon · Oct 29, 2013 · Viewed 7.8k times · Source

I'm currently using an msbuild file to copy some files to the public documents folder when my EXE is compiled. My current script includes this:

<Target Name="DeployToPublicDocuments"
              Inputs="@(DeploymentItems)"
              Outputs="$(PublicDocumentsFolder)%(Path)\%(DeploymentItems.RecursiveDir)%(DeploymentItems.Filename)%(DeploymentItems.Extension)">
        <Copy SourceFiles="%(DeploymentItems.FullPath)"
            DestinationFiles="$(PublicDocumentsFolder)%(Path)\%(DeploymentItems.RecursiveDir)%(DeploymentItems.Filename)%(DeploymentItems.Extension)"
                Condition="!Exists('$(PublicDocumentsFolder)%(Path)\%(DeploymentItems.RecursiveDir)%(DeploymentItems.Filename)%(DeploymentItems.Extension)')" />

This code only copies if the destination doesn't exist. However, I want to replace the destination if my source is newer. How do I modify my script to make that happen? I see the SkipUnchangedFiles flag, but it also compares file size to determine if the destination should be overwritten. That is not what I want.

Answer

Matt Slagle picture Matt Slagle · Nov 4, 2013

Your copy's conditional can be changed as follows:

    <Copy SourceFiles="%(DeploymentItems.FullPath)"
        DestinationFiles="$(PublicDocumentsFolder)%(Path)\%(RecursiveDir)%(Filename)%(DeploymentItems.Extension)"
            Condition="!Exists('$(PublicDocumentsFolder)%(Path)\%(RecursiveDir)%(Filename)%(DeploymentItems.Extension)') OR $([System.DateTime]::Parse('%(ModifiedTime)').Ticks) &gt; $([System.IO.File]::GetLastWriteTime('$(PublicDocumentsFolder)%(Path)\%(RecursiveDir)%(Filename)%(DeploymentItems.Extension)').Ticks)" />

%(ModifiedTime) = Modified Datetime of the source file

$([System.IO.File]::GetLastWriteTime($(PublicDocumentsFolder)%(Path)\%(RecursiveDir)%(Filename)%(DeploymentItems.Extension))) = Modified Datetime of the destination file, if it exists

Let me know if this works or not, did not test.