diff --git a/Data/DatabasePath.cs b/Data/DatabasePath.cs index 70cfe5a..7df8b3f 100644 --- a/Data/DatabasePath.cs +++ b/Data/DatabasePath.cs @@ -1,4 +1,5 @@ using System.IO; +using UtopiaCanteenSystem.Services.Logging; namespace UtopiaCanteenSystem.Data; @@ -11,6 +12,7 @@ public static class DatabasePath private static string? _appDataFolder; private static string? _dbPath; private static string _productFolderName = "UtopiaCanteenSystem"; + private static bool _useInteractiveLocalAppData; /// /// Use "UtopiaCanteenBackend" for the Windows Service; default is legacy WPF folder name. @@ -18,6 +20,7 @@ public static class DatabasePath public static void UseBackendServiceStorage() { _productFolderName = "UtopiaCanteenBackend"; + _useInteractiveLocalAppData = true; _appDataFolder = null; _dbPath = null; } @@ -25,6 +28,7 @@ public static class DatabasePath public static void UseClientStorage() { _productFolderName = "UtopiaCanteenClient"; + _useInteractiveLocalAppData = false; _appDataFolder = null; _dbPath = null; } @@ -37,11 +41,63 @@ public static class DatabasePath if (_appDataFolder != null) return _appDataFolder; - _appDataFolder = Path.Combine( + var localAppDataRoot = ResolveLocalAppDataRoot(); + _appDataFolder = Path.Combine(localAppDataRoot, _productFolderName); + Directory.CreateDirectory(_appDataFolder); + MigrateBackendSystemProfileStorageIfNeeded(_appDataFolder); + return _appDataFolder; + } + + private static string ResolveLocalAppDataRoot() + { + if (_useInteractiveLocalAppData) + { + var interactive = InteractiveUserPath.TryGetLocalAppDataPath(); + if (!string.IsNullOrWhiteSpace(interactive)) + return interactive; + } + + return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + } + + private static void MigrateBackendSystemProfileStorageIfNeeded(string newFolder) + { + if (!_useInteractiveLocalAppData) + return; + + var systemProfileFolder = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), _productFolderName); - Directory.CreateDirectory(_appDataFolder); - return _appDataFolder; + + if (string.Equals(systemProfileFolder, newFolder, StringComparison.OrdinalIgnoreCase) || + !Directory.Exists(systemProfileFolder)) + return; + + var oldDbPath = Path.Combine(systemProfileFolder, "utopia_canteen.db"); + var newDbPath = Path.Combine(newFolder, "utopia_canteen.db"); + if (File.Exists(oldDbPath) && !File.Exists(newDbPath)) + { + CopyIfMissing(oldDbPath, newDbPath); + CopyIfMissing(Path.Combine(systemProfileFolder, "utopia_canteen.db-wal"), Path.Combine(newFolder, "utopia_canteen.db-wal")); + CopyIfMissing(Path.Combine(systemProfileFolder, "utopia_canteen.db-shm"), Path.Combine(newFolder, "utopia_canteen.db-shm")); + } + + CopyIfMissing(Path.Combine(systemProfileFolder, "backend-settings.json"), Path.Combine(newFolder, "backend-settings.json")); + } + + private static void CopyIfMissing(string sourcePath, string destinationPath) + { + if (!File.Exists(sourcePath) || File.Exists(destinationPath)) + return; + + try + { + File.Copy(sourcePath, destinationPath); + } + catch + { + // If migration fails, the app will continue with files already present or create new ones. + } } /// diff --git a/Services/Logging/InteractiveUserPath.cs b/Services/Logging/InteractiveUserPath.cs index 35c69ce..5dc0f23 100644 --- a/Services/Logging/InteractiveUserPath.cs +++ b/Services/Logging/InteractiveUserPath.cs @@ -7,7 +7,7 @@ namespace UtopiaCanteenSystem.Services.Logging; /// /// Resolves the logged-on Windows user's profile paths when the app runs as a service (SYSTEM). /// -internal static class InteractiveUserPath +public static class InteractiveUserPath { public static string? TryGetLocalAppDataPath() {