using System.Diagnostics; using System.Reflection; namespace BSO.Launcher; /// /// Der Launcher aktualisiert sich selbst (wie bei MSCO): neue .exe vom Master laden (Signatur + SHA-256 geprueft), die /// laufende Datei in "*.old" umbenennen (geht unter Windows auch waehrend sie laeuft), die neue an ihre Stelle legen und /// neu starten. /// public static class SelfUpdate { public static string CurrentVersion => (Assembly.GetExecutingAssembly().GetCustomAttribute()?.InformationalVersion ?? "0.0.0") .Split('+')[0]; static string ExePath => Environment.ProcessPath ?? Application.ExecutablePath; public static bool IsNewer(string candidate, string than) => Version.TryParse(candidate, out var a) && Version.TryParse(than, out var b) && a > b; /// Nach einem Update: die alte Datei aufraeumen. public static void CleanupOldVersion() { try { string old = ExePath + ".old"; if (File.Exists(old)) File.Delete(old); } catch { /* laeuft evtl. noch kurz */ } } /// Startoption der neuen Version nach einem Selbst-Update: auf das Ende der alten warten. public const string AfterUpdateArg = "--after-update"; public static async Task Install(Api.Release release, Action progress) { byte[] data = await Api.Download(release, progress); string exe = ExePath, fresh = exe + ".new", old = exe + ".old"; await File.WriteAllBytesAsync(fresh, data); if (File.Exists(old)) File.Delete(old); File.Move(exe, old); File.Move(fresh, exe); // Die neue Version wartet, bis diese hier beendet ist (sonst meldet sie "laeuft schon" und beendet sich) var start = new ProcessStartInfo(exe) { UseShellExecute = true }; start.ArgumentList.Add(AfterUpdateArg); if (!Installer.RunningInstalled) start.ArgumentList.Add("--portable"); if (Api.Dev) start.ArgumentList.Add(Api.DevArg); Process.Start(start); return release.version; } }