using Microsoft.Win32; using System; using System.Diagnostics; namespace Bedtimer { public static class AutoStart { private const string RunKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"; private const string ValueName = "Bedtimer"; // Public API used by UI public static bool IsEnabled() => ExistsHKLM(); public static void SetEnabled(bool enabled) { try { if (enabled) EnsureHKLM(); else DisableHKLM(); } catch (UnauthorizedAccessException) { // Relaunch self elevated to write HKLM var exe = Environment.ProcessPath!; var args = enabled ? "--autostart-admin on" : "--autostart-admin off"; Process.Start(new ProcessStartInfo(exe, args) { UseShellExecute = true, Verb = "runas" }); } } // Branch the app handles on startup (see App.xaml.cs patch below) public static void HandleAdminArgs(string[] args) { // args: ["--autostart-admin", "on"|"off"] if (args.Length >= 3 && args[1] == "--autostart-admin") { if (string.Equals(args[2], "on", StringComparison.OrdinalIgnoreCase)) EnsureHKLM(); else DisableHKLM(); Environment.Exit(0); } } // -------- Internal HKLM helpers (explicit registry view) -------- private static RegistryKey OpenHKLM() { var view = Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32; return RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, view); } private static bool ExistsHKLM() { using var root = OpenHKLM(); using var key = root.OpenSubKey(RunKey, false); return key?.GetValue(ValueName) is string; } private static void EnsureHKLM() { using var root = OpenHKLM(); using var key = root.CreateSubKey(RunKey, true); var exe = Environment.ProcessPath!; var target = $"\"{exe}\""; // no args; single EXE handles all key.SetValue(ValueName, target, RegistryValueKind.String); // (Optional) Clean up any old per-user Run entries so we don't double-start try { using var hkcu = Registry.CurrentUser.CreateSubKey(RunKey, true); hkcu.DeleteValue(ValueName, false); } catch { /* ignore */ } } private static void DisableHKLM() { using var root = OpenHKLM(); using var key = root.CreateSubKey(RunKey, true); key.DeleteValue(ValueName, false); } } }