JD2022-TU1/main/tools/legacy/BetaVersionInstaller/RoboCopy.cs

75 lines
No EOL
2.6 KiB
C#

using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace BetaVersionLauncher
{
/// <summary>
/// Replicates a directory to a target directory.
/// </summary>
public class RoboCopy
{
public static void ReplicateDirectory(string source, string destination)
{
var sourceFiles = GetRelativeFilesRecursive(source);
var destinationFiles = GetRelativeFilesRecursive(destination);
// Copy new files.
foreach (var file in sourceFiles)
{
ReplicateFile(Path.Combine(source, file), Path.Combine(destination, file));
}
// Remove old files.
foreach (var destinationFile in destinationFiles)
{
if (!sourceFiles.Contains(destinationFile))
{
string file = Path.Combine(destination, destinationFile);
File.SetAttributes(file, FileAttributes.Normal);
File.Delete(file);
}
}
}
private static HashSet<string> GetRelativeFilesRecursive(string folder)
{
if (!Directory.Exists(folder))
{
return new HashSet<string>();
}
return new HashSet<string>(Directory.GetFiles(folder, "*.*", SearchOption.AllDirectories).Select(file => ToRelative(folder, file)));
}
private static void ReplicateFile(string source, string destination)
{
CreateDirectory(Path.GetDirectoryName(destination));
var sourceFileInfo = new FileInfo(source);
var destinationFileInfo = new FileInfo(destination);
if (!destinationFileInfo.Exists || sourceFileInfo.Length != destinationFileInfo.Length ||
sourceFileInfo.LastWriteTimeUtc != destinationFileInfo.LastWriteTimeUtc)
{
if (destinationFileInfo.Exists && destinationFileInfo.IsReadOnly)
{
File.SetAttributes(destination, FileAttributes.Normal);
}
File.Copy(source, destination, true);
}
}
private static void CreateDirectory(string directory)
{
if (!Directory.Exists(directory))
{
CreateDirectory(Path.GetDirectoryName(directory));
Directory.CreateDirectory(directory);
}
}
private static string ToRelative(string folder, string file)
{
return file.Substring(folder.Length).Replace('/', '\\').TrimStart('\\');
}
}
}