Last active
September 26, 2024 07:33
-
-
Save psulek/f313f0e6e7a2c8d07cc105d39130cf62 to your computer and use it in GitHub Desktop.
MSBuild Task CopyIfNewer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |
<UsingTask TaskName="CopyIfNewer" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildBinPath)\Microsoft.Build.Tasks.Core.dll"> | |
<ParameterGroup> | |
<SourceFiles ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true"/> | |
<TargetFiles ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true"/> | |
</ParameterGroup> | |
<Task> | |
<Using Namespace="System"/> | |
<Using Namespace="System.IO"/> | |
<Using Namespace="Microsoft.Build.Framework"/> | |
<Using Namespace="Microsoft.Build.Utilities"/> | |
<Code Type="Fragment" Language="cs"> | |
<![CDATA[ | |
Success = SourceFiles.Length == TargetFiles.Length; | |
if (!Success) | |
{ | |
Log.LogError("SourceFiles and TargetFiles must have the same number of elements."); | |
} | |
else | |
{ | |
for (int i = 0; i < SourceFiles.Length; i++) | |
{ | |
string sourceFile = SourceFiles[i].ItemSpec; | |
string targetFile = TargetFiles[i].ItemSpec; | |
if (!File.Exists(sourceFile)) | |
{ | |
Log.LogMessage(MessageImportance.High, $"Source file does not exist: {sourceFile}"); | |
continue; | |
} | |
bool shouldCopy = !File.Exists(targetFile); | |
bool sameModified = false; | |
if (!shouldCopy) | |
{ | |
var sourceLastModified = File.GetLastWriteTime(sourceFile); | |
var targetLastModified = File.GetLastWriteTime(targetFile); | |
shouldCopy = sourceLastModified > targetLastModified; | |
sameModified = sourceLastModified == targetLastModified; | |
} | |
if (shouldCopy) | |
{ | |
try | |
{ | |
File.Copy(sourceFile, targetFile, true); | |
Log.LogMessage(MessageImportance.High, $"Copied file '{sourceFile}' -> '{targetFile}' succeed."); | |
} | |
catch (Exception ex) | |
{ | |
Log.LogError($"Error copying '{sourceFile}' to '{targetFile}': {ex.Message}"); | |
Success = false; | |
break; | |
} | |
} else { | |
string reason = sameModified ? "same modified time" : "target is newer"; | |
Log.LogMessage(MessageImportance.High, $"Skipping copy file '{sourceFile}' -> '{targetFile}' ({reason})"); | |
} | |
} | |
} | |
]]> | |
</Code> | |
</Task> | |
</UsingTask> | |
<Target Name="CopyFiles"> | |
<ItemGroup> | |
<SourceFiles Include="path\to\source\file1.txt;path\to\source\file2.txt" /> | |
<TargetFiles Include="path\to\target\file1.txt;path\to\target\file2.txt" /> | |
</ItemGroup> | |
<CopyIfNewer SourceFiles="@(SourceFiles)" TargetFiles="@(TargetFiles)" /> | |
</Target> | |
</Project> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Same can be done by complicated way using msbuild only stuff, example: