Files
duempelkas/src/Duempelkas.Desktop/Program.cs
T

129 lines
4.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Duempelkas.Infrastructure;
using Duempelkas.Infrastructure.Persistence;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Photino.Blazor;
using System.Runtime.InteropServices;
namespace Duempelkas.Desktop;
class Program
{
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
private static extern int SetCurrentProcessExplicitAppUserModelID(string appID);
[STAThread]
static void Main(string[] args)
{
if (OperatingSystem.IsWindows())
{
// Ensure Windows taskbar does not group this process under generic dotnet host identity.
SetCurrentProcessExplicitAppUserModelID("Duempelkas.Desktop");
}
var appBuilder = PhotinoBlazorAppBuilder.CreateDefault(args);
// Use a per-user writable DB location so debugging via dotnet host works reliably.
var appDataDir = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"Duempelkas");
var isolated = false;
#if DEBUG
var directoryIndex = Array.IndexOf(args, "--data-directory");
if (directoryIndex >= 0)
{
if (directoryIndex + 1 >= args.Length) throw new ArgumentException("Datenordner fehlt.");
appDataDir = Path.GetFullPath(args[directoryIndex + 1]);
isolated = true;
}
#endif
Directory.CreateDirectory(appDataDir);
var dbPath = Path.Combine(appDataDir, "duempelkas.db");
// One-time compatibility: keep existing data if older versions stored DB next to the app executable.
var legacyExeDirectory = Path.GetDirectoryName(Environment.ProcessPath ?? AppContext.BaseDirectory) ?? AppContext.BaseDirectory;
var legacyDbPath = Path.Combine(legacyExeDirectory, "duempelkas.db");
if (!isolated && !File.Exists(dbPath) && File.Exists(legacyDbPath))
{
try
{
using var source = new Microsoft.Data.Sqlite.SqliteConnection($"Data Source={legacyDbPath};Mode=ReadOnly");
using var target = new Microsoft.Data.Sqlite.SqliteConnection($"Data Source={dbPath}");
source.Open();
target.Open();
source.BackupDatabase(target);
}
catch (Exception ex)
{
throw new InvalidOperationException("Die vorhandene Datenbank konnte nicht übernommen werden. Der Start wurde abgebrochen; die ursprüngliche Datei bleibt erhalten.", ex);
}
}
appBuilder.Services.AddInfrastructure(new Microsoft.Data.Sqlite.SqliteConnectionStringBuilder { DataSource = dbPath }.ToString(), appDataDir);
appBuilder.RootComponents.Add<Duempelkas.App.Components.App>("app");
var app = appBuilder.Build();
app.MainWindow.StartUrl = PhotinoWebViewManager.AppBaseUri;
// Force the native window icon for title bar + taskbar representation.
var iconPath = Path.Combine(AppContext.BaseDirectory, "Assets", "app-icon.ico");
if (File.Exists(iconPath))
{
app.MainWindow.SetIconFile(iconPath);
}
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<FinanceDbContext>();
db.Database.Migrate();
}
// Load saved window size or use defaults
var settingsPath = Path.Combine(appDataDir, "window.json");
int savedWidth = 1280, savedHeight = 800;
if (File.Exists(settingsPath))
{
try
{
var json = File.ReadAllText(settingsPath);
var doc = System.Text.Json.JsonDocument.Parse(json);
savedWidth = doc.RootElement.GetProperty("width").GetInt32();
savedHeight = doc.RootElement.GetProperty("height").GetInt32();
}
catch { /* use defaults on parse error */ }
}
app.MainWindow
.SetTitle(isolated ? "Dümpelkas – Testdaten" : "Dümpelkas – Kassenbuch")
.SetSize(savedWidth, savedHeight)
.SetUseOsDefaultSize(false);
app.MainWindow.MinWidth = 768;
app.MainWindow.MinHeight = 480;
// Persist window size on resize
app.MainWindow.RegisterSizeChangedHandler((_, size) =>
{
try
{
var dir = Path.GetDirectoryName(settingsPath)!;
Directory.CreateDirectory(dir);
File.WriteAllText(settingsPath,
System.Text.Json.JsonSerializer.Serialize(new { width = size.Width, height = size.Height }));
}
catch { /* ignore save errors */ }
});
AppDomain.CurrentDomain.UnhandledException += (sender, error) =>
{
app.MainWindow.ShowMessage("Schwerwiegender Fehler", error.ExceptionObject.ToString());
};
app.Run();
}
}