using System.Diagnostics; namespace SwyxTray; internal static class Program { /// /// Sitzungsweit eindeutig (Local\), nicht maschinenweit: bei /// Terminalserver-Betrieb soll je Sitzung eine Instanz laufen duerfen, /// weil jede Sitzung ihren eigenen CLMgr hat. /// private const string InstanceMutexName = @"Local\SwyxTray.SingleInstance"; [STAThread] private static void Main(string[] args) { Log.VerboseEnabled = args.Any(a => a.Equals("--verbose", StringComparison.OrdinalIgnoreCase) || a.Equals("-v", StringComparison.OrdinalIgnoreCase)); using var mutex = new Mutex(initiallyOwned: true, InstanceMutexName, out var isFirstInstance); if (!isFirstInstance) { Log.Info("Eine Instanz laeuft bereits in dieser Sitzung — Start abgebrochen."); return; } // Muss vor dem ersten COM-Aufruf stehen, sonst kann CLMgr keine // Ereignisse in diesen Prozess zurueckrufen (E_ACCESSDENIED bei Advise). var securityResult = NativeMethods.InitializeComSecurity(); ApplicationConfiguration.Initialize(); // Die App hat kein Fenster. Ein unbehandelter Fehler wuerde sie sonst // kommentarlos beenden, deshalb wird alles protokolliert. Application.ThreadException += (_, e) => Log.Error("Unbehandelter Fehler im UI-Thread.", e.Exception); AppDomain.CurrentDomain.UnhandledException += (_, e) => Log.Error("Unbehandelter Fehler.", e.ExceptionObject as Exception); Log.Info($"SwyxTray gestartet (PID {Environment.ProcessId}, " + $"Sitzung {Process.GetCurrentProcess().SessionId}, " + $"{(Environment.Is64BitProcess ? "x64" : "x86")})."); if (securityResult != 0) { Log.Info($"CoInitializeSecurity lieferte 0x{securityResult:X8}" + (NativeMethods.IsTooLate(securityResult) ? " (RPC_E_TOO_LATE — COM war bereits initialisiert)." : ".")); } try { using var context = new TrayApplicationContext(); Application.Run(context); } finally { TrayIcons.DisposeAll(); Log.Info("SwyxTray beendet."); } } }