diff --git a/LANCommander.SDK/AppPaths.cs b/LANCommander.SDK/AppPaths.cs index f1418579..1e2074b6 100644 --- a/LANCommander.SDK/AppPaths.cs +++ b/LANCommander.SDK/AppPaths.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Reflection; +using LANCommander.SDK.Helpers; namespace LANCommander.SDK; @@ -18,22 +19,10 @@ public static class AppPaths var baseDirectory = Directory.GetCurrentDirectory(); - if (IsDirectoryWritable(baseDirectory)) - { + if (DirectoryHelper.IsDirectoryWritable(baseDirectory)) _configDirectory = baseDirectory; - } else - { - var (company, product) = GetCompanyAndProduct(); - var userRoot = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); - - var appDataPath = Path.Combine(userRoot, company, product); - - if (!Directory.Exists(appDataPath)) - Directory.CreateDirectory(appDataPath); - - _configDirectory = appDataPath; - } + _configDirectory = GetAppDataPath(); _configDirectory = Path.Combine(_configDirectory, "Data"); @@ -43,29 +32,19 @@ public static class AppPaths return _configDirectory; } - private static bool IsDirectoryWritable(string path) + public static string GetAppDataPath() { - try - { - Directory.CreateDirectory(path); - - var probeFile = Path.Combine(path, $".writetest.{Guid.NewGuid():N}.tmp"); - - using (var fs = new FileStream(probeFile, FileMode.CreateNew, FileAccess.Write, FileShare.None)) - { - fs.WriteByte(0); - } - - File.Delete(probeFile); - - return true; - } - catch - { - return false; - } + var (company, product) = GetCompanyAndProduct(); + var userRoot = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + + var appDataPath = Path.Combine(userRoot, company, product); + + if (!Directory.Exists(appDataPath)) + Directory.CreateDirectory(appDataPath); + + return appDataPath; } - + private static (string? Company, string? Product) GetCompanyAndProduct() { var assembly = Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly(); diff --git a/LANCommander.SDK/Helpers/DirectoryHelper.cs b/LANCommander.SDK/Helpers/DirectoryHelper.cs index 349d8d50..2971e481 100644 --- a/LANCommander.SDK/Helpers/DirectoryHelper.cs +++ b/LANCommander.SDK/Helpers/DirectoryHelper.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Reflection; using System.Text; namespace LANCommander.SDK.Helpers @@ -31,5 +32,79 @@ namespace LANCommander.SDK.Helpers catch { } } } + + public static bool IsDirectoryWritable(string path) + { + try + { + Directory.CreateDirectory(path); + + var probeFile = Path.Combine(path, $".writetest.{Guid.NewGuid():N}.tmp"); + + using (var fs = new FileStream(probeFile, FileMode.CreateNew, FileAccess.Write, FileShare.None)) + { + fs.WriteByte(0); + } + + File.Delete(probeFile); + + return true; + } + catch + { + return false; + } + } + + public static void MoveContents(string source, string destination) + { + if (String.IsNullOrWhiteSpace(source)) + throw new ArgumentException("Source directory cannot be empty", nameof(source)); + + if (String.IsNullOrWhiteSpace(destination)) + throw new ArgumentException("Destination directory cannot be empty", nameof(destination)); + + if (!Directory.Exists(source)) + throw new DirectoryNotFoundException(source); + + MoveDirectoryRecursive(source, destination); + } + + private static void MoveDirectoryRecursive(string source, string destination) + { + Directory.CreateDirectory(destination); + + foreach (var file in Directory.GetFiles(source)) + { + var fileName = Path.GetFileName(file); + var destinationFile = Path.Combine(destination, fileName); + + if (File.Exists(destinationFile)) + BackupExistingFile(destinationFile); + + File.Move(file, destinationFile); + } + + foreach (var directory in Directory.GetDirectories(source)) + { + var directoryName = Path.GetFileName(directory); + var destinationDirectory = Path.Combine(destination, directoryName); + + MoveDirectoryRecursive(directory, destinationDirectory); + + if (Directory.GetFileSystemEntries(directory).Length == 0) + Directory.Delete(directory, true); + } + } + + private static void BackupExistingFile(string destination) + { + var backupFile = destination + ".bak"; + + if (File.Exists(backupFile)) + BackupExistingFile(backupFile); + + File.Move(destination, backupFile); + } } } diff --git a/LANCommander.Server/Migrations/EncapsulateUserData.cs b/LANCommander.Server/Migrations/EncapsulateUserData.cs index 7e24e275..e10c9750 100644 --- a/LANCommander.Server/Migrations/EncapsulateUserData.cs +++ b/LANCommander.Server/Migrations/EncapsulateUserData.cs @@ -1,5 +1,6 @@ using System.Reflection; using LANCommander.SDK; +using LANCommander.SDK.Helpers; using LANCommander.SDK.Migrations; using Semver; @@ -16,22 +17,10 @@ public class EncapsulateUserData( { var baseDirectory = Directory.GetCurrentDirectory(); - if (IsDirectoryWritable(baseDirectory)) - { + if (DirectoryHelper.IsDirectoryWritable(baseDirectory)) _oldConfigDirectory = baseDirectory; - } else - { - var (company, product) = GetCompanyAndProduct(); - var userRoot = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); - - var appDataPath = Path.Combine(userRoot, company, product); - - if (!Directory.Exists(appDataPath)) - Directory.CreateDirectory(appDataPath); - - _oldConfigDirectory = appDataPath; - } + _oldConfigDirectory = AppPaths.GetAppDataPath(); MoveOldPath("Backups"); MoveOldPath("Media"); @@ -50,49 +39,19 @@ public class EncapsulateUserData( { try { - logger.LogInformation($"Moving old config directory/file \"{path}\""); + var source = Path.Combine(_oldConfigDirectory, path); + var destination = AppPaths.GetConfigPath(path); - if (Directory.Exists(Path.Combine(_oldConfigDirectory, path))) - Directory.Move(Path.Combine(_oldConfigDirectory, path), AppPaths.GetConfigPath(path)); - else if (File.Exists(Path.Combine(_oldConfigDirectory, path))) - File.Move(Path.Combine(_oldConfigDirectory, path), AppPaths.GetConfigPath(path)); + if (source == destination) + return; + + logger.LogInformation($"Moving old config directory/file \"{path}\""); + + DirectoryHelper.MoveContents(source, destination); } catch (Exception ex) { logger.LogError(ex, "Error while moving old config directory/file"); } } - - private bool IsDirectoryWritable(string path) - { - try - { - Directory.CreateDirectory(path); - - var probeFile = Path.Combine(path, $".writetest.{Guid.NewGuid():N}.tmp"); - - using (var fs = new FileStream(probeFile, FileMode.CreateNew, FileAccess.Write, FileShare.None)) - { - fs.WriteByte(0); - } - - File.Delete(probeFile); - - return true; - } - catch - { - return false; - } - } - - private(string? Company, string? Product) GetCompanyAndProduct() - { - var assembly = Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly(); - - var company = assembly.GetCustomAttribute()?.Company; - var product = assembly.GetCustomAttribute()?.Product; - - return (company, product); - } } \ No newline at end of file