fixes : auto deployment and bug fixes
parent
25a808907d
commit
4bf3cced5f
13
App.xaml.cs
13
App.xaml.cs
|
|
@ -12,11 +12,21 @@ namespace UtopiaCanteenSystem;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class App : Application
|
public partial class App : Application
|
||||||
{
|
{
|
||||||
|
private static Mutex _mutex;
|
||||||
private System.Timers.Timer? _syncTimer;
|
private System.Timers.Timer? _syncTimer;
|
||||||
private int _isSyncRunning;
|
private int _isSyncRunning;
|
||||||
|
|
||||||
protected override void OnStartup(StartupEventArgs e)
|
protected override void OnStartup(StartupEventArgs e)
|
||||||
{
|
{
|
||||||
|
bool isNewInstance;
|
||||||
|
_mutex = new Mutex(true, "UtopiaCanteenSystemMutex", out isNewInstance);
|
||||||
|
|
||||||
|
if (!isNewInstance)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Another instance of the application is already running.", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||||
|
Current.Shutdown();
|
||||||
|
return;
|
||||||
|
}
|
||||||
base.OnStartup(e);
|
base.OnStartup(e);
|
||||||
|
|
||||||
// Build services (simple composition; no DI container)
|
// Build services (simple composition; no DI container)
|
||||||
|
|
@ -52,6 +62,8 @@ public partial class App : Application
|
||||||
{
|
{
|
||||||
DataContext = mainViewModel
|
DataContext = mainViewModel
|
||||||
};
|
};
|
||||||
|
// Set the window to open maximized
|
||||||
|
mainWindow.WindowState = WindowState.Maximized;
|
||||||
mainWindow.Show();
|
mainWindow.Show();
|
||||||
|
|
||||||
// Background sync: every 15 minutes, POST unsynced lunch_order_transactions to API
|
// Background sync: every 15 minutes, POST unsynced lunch_order_transactions to API
|
||||||
|
|
@ -83,6 +95,7 @@ public partial class App : Application
|
||||||
|
|
||||||
protected override void OnExit(ExitEventArgs e)
|
protected override void OnExit(ExitEventArgs e)
|
||||||
{
|
{
|
||||||
|
_mutex.ReleaseMutex();
|
||||||
_syncTimer?.Stop();
|
_syncTimer?.Stop();
|
||||||
_syncTimer?.Dispose();
|
_syncTimer?.Dispose();
|
||||||
base.OnExit(e);
|
base.OnExit(e);
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,12 @@ namespace UtopiaCanteenSystem.Data;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SQLite DbContext for Labour and lunch_order_transactions (scan records) tables.
|
/// SQLite DbContext for Labour and lunch_order_transactions (scan records) tables.
|
||||||
/// Database file is created in application directory on first run.
|
/// Database file is stored under LocalApplicationData so it persists across app updates
|
||||||
|
/// when deployed from a file server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AppDbContext : DbContext
|
public class AppDbContext : DbContext
|
||||||
{
|
{
|
||||||
private static readonly string DbPath = Path.Combine(
|
private static string DbPath => DatabasePath.GetDbPath();
|
||||||
AppDomain.CurrentDomain.BaseDirectory,
|
|
||||||
"utopia_canteen.db");
|
|
||||||
|
|
||||||
public DbSet<Labour> Labour { get; set; }
|
public DbSet<Labour> Labour { get; set; }
|
||||||
public DbSet<ScanRecord> LunchOrderTransactions { get; set; }
|
public DbSet<ScanRecord> LunchOrderTransactions { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace UtopiaCanteenSystem.Data;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Central location for persistent paths (database and config). Uses LocalApplicationData
|
||||||
|
/// so data survives app updates when the application is deployed from a file server.
|
||||||
|
/// </summary>
|
||||||
|
public static class DatabasePath
|
||||||
|
{
|
||||||
|
private static string? _appDataFolder;
|
||||||
|
private static string? _dbPath;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Folder under LocalApplicationData for DB and config. Created on first use.
|
||||||
|
/// </summary>
|
||||||
|
public static string GetAppDataFolder()
|
||||||
|
{
|
||||||
|
if (_appDataFolder != null)
|
||||||
|
return _appDataFolder;
|
||||||
|
|
||||||
|
_appDataFolder = Path.Combine(
|
||||||
|
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||||||
|
"UtopiaCanteenSystem");
|
||||||
|
Directory.CreateDirectory(_appDataFolder);
|
||||||
|
return _appDataFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Full path to the SQLite database file. If a DB exists in the legacy app-directory
|
||||||
|
/// location, it is copied to the new location once.
|
||||||
|
/// </summary>
|
||||||
|
public static string GetDbPath()
|
||||||
|
{
|
||||||
|
if (_dbPath != null)
|
||||||
|
return _dbPath;
|
||||||
|
|
||||||
|
var folder = GetAppDataFolder();
|
||||||
|
_dbPath = Path.Combine(folder, "utopia_canteen.db");
|
||||||
|
MigrateLegacyDbIfNeeded(_dbPath);
|
||||||
|
return _dbPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Full path to appsettings.json (remember-me credentials and other config).
|
||||||
|
/// Stored in the same persistent folder so it survives updates. If a config exists
|
||||||
|
/// in the legacy app-directory location, it is copied to the new location once.
|
||||||
|
/// </summary>
|
||||||
|
public static string GetConfigPath()
|
||||||
|
{
|
||||||
|
var folder = GetAppDataFolder();
|
||||||
|
var newPath = Path.Combine(folder, "appsettings.json");
|
||||||
|
MigrateLegacyConfigIfNeeded(newPath);
|
||||||
|
return newPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void MigrateLegacyDbIfNeeded(string newPath)
|
||||||
|
{
|
||||||
|
if (File.Exists(newPath))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var legacyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "utopia_canteen.db");
|
||||||
|
if (!File.Exists(legacyPath))
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.Copy(legacyPath, newPath);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// If copy fails, app will start with a new DB at new path.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void MigrateLegacyConfigIfNeeded(string newPath)
|
||||||
|
{
|
||||||
|
if (File.Exists(newPath))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var legacyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "appsettings.json");
|
||||||
|
if (!File.Exists(legacyPath))
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.Copy(legacyPath, newPath);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// If copy fails, app will start with a new config at new path.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,7 +13,7 @@ public class DbContextFactory : IDbContextFactory<AppDbContext>
|
||||||
static DbContextFactory()
|
static DbContextFactory()
|
||||||
{
|
{
|
||||||
var builder = new DbContextOptionsBuilder<AppDbContext>();
|
var builder = new DbContextOptionsBuilder<AppDbContext>();
|
||||||
var dbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "utopia_canteen.db");
|
var dbPath = DatabasePath.GetDbPath();
|
||||||
builder.UseSqlite($"Data Source={dbPath}");
|
builder.UseSqlite($"Data Source={dbPath}");
|
||||||
Options = builder.Options;
|
Options = builder.Options;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@
|
||||||
Icon="pack://siteoforigin:,,,/assets/favicon.ico"
|
Icon="pack://siteoforigin:,,,/assets/favicon.ico"
|
||||||
MinHeight="400" MinWidth="480"
|
MinHeight="400" MinWidth="480"
|
||||||
Width="900" Height="700"
|
Width="900" Height="700"
|
||||||
WindowStartupLocation="CenterScreen">
|
WindowStartupLocation="CenterScreen"
|
||||||
|
WindowState="Maximized">
|
||||||
<Grid>
|
<Grid>
|
||||||
<ContentControl Content="{Binding CurrentViewModel}"
|
<ContentControl Content="{Binding CurrentViewModel}"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<ApplicationRevision>10</ApplicationRevision>
|
||||||
|
<ApplicationVersion>1.0.0.*</ApplicationVersion>
|
||||||
|
<BootstrapperEnabled>True</BootstrapperEnabled>
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<CreateDesktopShortcut>True</CreateDesktopShortcut>
|
||||||
|
<CreateWebPageOnPublish>False</CreateWebPageOnPublish>
|
||||||
|
<GenerateManifests>true</GenerateManifests>
|
||||||
|
<Install>True</Install>
|
||||||
|
<InstallFrom>Unc</InstallFrom>
|
||||||
|
<InstallUrl>\\FileServer\Edata\Deployments-by-DotNet-Team\UtopiaCanteenSystem\</InstallUrl>
|
||||||
|
<IsRevisionIncremented>True</IsRevisionIncremented>
|
||||||
|
<IsWebBootstrapper>False</IsWebBootstrapper>
|
||||||
|
<MapFileExtensions>True</MapFileExtensions>
|
||||||
|
<OpenBrowserOnPublish>False</OpenBrowserOnPublish>
|
||||||
|
<Platform>Any CPU</Platform>
|
||||||
|
<PublishDir>bin\Release\net8.0-windows\win-x86\app.publish\</PublishDir>
|
||||||
|
<PublishUrl>\\FileServer\Edata\Deployments-by-DotNet-Team\UtopiaCanteenSystem\</PublishUrl>
|
||||||
|
<PublishProtocol>ClickOnce</PublishProtocol>
|
||||||
|
<PublishReadyToRun>False</PublishReadyToRun>
|
||||||
|
<PublishSingleFile>True</PublishSingleFile>
|
||||||
|
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
|
||||||
|
<SelfContained>True</SelfContained>
|
||||||
|
<SignatureAlgorithm>(none)</SignatureAlgorithm>
|
||||||
|
<SignManifests>False</SignManifests>
|
||||||
|
<SkipPublishVerification>false</SkipPublishVerification>
|
||||||
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
|
<UpdateEnabled>True</UpdateEnabled>
|
||||||
|
<UpdateMode>Foreground</UpdateMode>
|
||||||
|
<UpdateRequired>False</UpdateRequired>
|
||||||
|
<UpdateUrl>\\FileServer\Edata\Deployments-by-DotNet-Team\UtopiaCanteenSystem\</UpdateUrl>
|
||||||
|
<WebPageFileName>Publish.html</WebPageFileName>
|
||||||
|
<History>True|2026-02-12T06:22:02.6537306Z||;True|2026-02-12T10:57:16.2775876+05:00||;True|2026-02-12T10:50:58.6968682+05:00||;False|2026-02-12T10:49:27.1867616+05:00||;True|2026-02-12T10:44:55.6022990+05:00||;True|2026-02-11T17:00:04.2786466+05:00||;True|2026-02-11T16:54:37.5052808+05:00||;True|2026-02-11T16:39:26.1892892+05:00||;True|2026-02-11T16:30:57.2420414+05:00||;True|2026-02-11T16:20:44.4749529+05:00||;</History>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -3,11 +3,13 @@ using System.Linq;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using UtopiaCanteenSystem.Data;
|
||||||
|
|
||||||
namespace UtopiaCanteenSystem.Services;
|
namespace UtopiaCanteenSystem.Services;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Simple JSON-backed configuration stored alongside the app binaries.
|
/// JSON-backed configuration (including remember-me credentials) stored under
|
||||||
|
/// LocalApplicationData so it survives app updates when deployed from a file server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ConfigService : IConfigService
|
public class ConfigService : IConfigService
|
||||||
{
|
{
|
||||||
|
|
@ -16,7 +18,7 @@ public class ConfigService : IConfigService
|
||||||
|
|
||||||
public ConfigService()
|
public ConfigService()
|
||||||
{
|
{
|
||||||
_configPath = Path.Combine(AppContext.BaseDirectory, "appsettings.json");
|
_configPath = DatabasePath.GetConfigPath();
|
||||||
_config = LoadConfig();
|
_config = LoadConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue