using System.IO; using System.Windows; using Hardcodet.Wpf.TaskbarNotification; using JournalBot.Shared; using Microsoft.Extensions.Configuration; namespace JournalBot.Tray; public partial class App : Application { private TaskbarIcon? _tray; private MainWindow? _window; private BotRunner _runner = null!; private RuntimeReader _reader = null!; protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); var config = new ConfigurationBuilder() .SetBasePath(AppContext.BaseDirectory) .AddJsonFile("appsettings.json", optional: false) .Build(); var py = config["JournalBot:PythonExe"]!; var workingDir = config["JournalBot:WorkingDir"]!; var runtimePath = config["JournalBot:RuntimePath"]!; _runner = new BotRunner(py, workingDir); _reader = new RuntimeReader(runtimePath); _window = new MainWindow(_runner, _reader); _tray = new TaskbarIcon { ToolTipText = "JournalBot" }; try { // icon.ico is embedded as a WPF Resource (see .csproj), so load it // from the resource stream — not the filesystem, which would fail // because no icon.ico is copied next to the EXE. var uri = new Uri("pack://application:,,,/icon.ico", UriKind.Absolute); using var stream = Application.GetResourceStream(uri).Stream; _tray.Icon = new System.Drawing.Icon(stream); } catch (Exception ex) { // Missing/corrupt icon must not prevent startup; tray still works. // Don't swallow silently — a blank tray icon is otherwise a mystery. System.Diagnostics.Debug.WriteLine($"Tray icon load failed: {ex}"); } _tray.TrayLeftMouseUp += (_, _) => ToggleWindow(); _tray.ContextMenu = BuildMenu(); } private System.Windows.Controls.ContextMenu BuildMenu() { var menu = new System.Windows.Controls.ContextMenu(); void Add(string header, Action onClick) { var mi = new System.Windows.Controls.MenuItem { Header = header }; mi.Click += (_, _) => onClick(); menu.Items.Add(mi); } Add("Ingest", () => _window!.TriggerCommand("ingest")); Add("Process", () => _window!.TriggerCommand("process")); Add("Both", () => _window!.TriggerCommand("both")); menu.Items.Add(new System.Windows.Controls.Separator()); Add("Fenster öffnen", ShowWindow); Add("Beenden", () => Shutdown()); return menu; } private void ToggleWindow() { if (_window!.IsVisible) _window.Hide(); else ShowWindow(); } private void ShowWindow() { _window!.Show(); _window.Activate(); } protected override void OnExit(ExitEventArgs e) { _tray?.Dispose(); base.OnExit(e); } }