using System.Diagnostics; using System.IO; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Animation; namespace DeskCoreSetup; public partial class MainWindow : Window { private readonly bool _uninstall; private int _page; private bool _busy; private bool _done; private string? _installedExe; public MainWindow(bool uninstall) { InitializeComponent(); _uninstall = uninstall; VersionText.Text = $"Version {Installer.Version}"; LicenseText.Text = Installer.LicenseText; DirBox.Text = Installer.InstalledDir ?? Installer.DefaultDir; DesktopLinkBox.IsChecked = Installer.InstalledDir is null || Installer.DesktopLinkExists; AutostartBox.IsChecked = Installer.AutostartEnabled; if (Installer.InstalledDir is null && Installer.LegacyInstallDir is not null) { UpdateHint.Visibility = Visibility.Visible; UpdateHintText.Text = "Die bisherige Version „DeskHub“ wird durch DeskCore ersetzt. Deine Kategorien und Einstellungen werden übernommen."; } else if (Installer.InstalledDir is not null) { UpdateHint.Visibility = Visibility.Visible; UpdateHintText.Text = Installer.InstalledVersion == Installer.Version ? $"DeskCore {Installer.Version} ist bereits installiert und wird neu installiert. Deine Kategorien und Einstellungen bleiben erhalten." : $"Die vorhandene Installation (Version {Installer.InstalledVersion}) wird durch Version {Installer.Version} ersetzt. Deine Kategorien und Einstellungen bleiben erhalten."; } if (_uninstall) { Title = WindowTitle.Text = "DeskCore deinstallieren"; Steps.Visibility = Visibility.Collapsed; ShowOnly(PageUninstall); NextButton.Content = "Deinstallieren"; BackButton.Visibility = Visibility.Collapsed; LoadDataInfo(); } else ShowPage(0); } // ---------- Seiten ---------- private void ShowOnly(UIElement page) { foreach (var p in new UIElement[] { PageWelcome, PageLicense, PageOptions, PageProgress, PageUninstall }) p.Visibility = p == page ? Visibility.Visible : Visibility.Collapsed; } private void ShowPage(int page) { _page = page; ShowOnly(page switch { 0 => PageWelcome, 1 => PageLicense, 2 => PageOptions, _ => PageProgress }); var steps = new[] { Step0, Step1, Step2, Step3 }; for (int i = 0; i < steps.Length; i++) { var label = ((string)steps[i].Tag ?? (string)(steps[i].Tag = steps[i].Text)); steps[i].Text = i < page || (_done && i == page) ? $"✓ {label}" : label; steps[i].FontWeight = i == page ? FontWeights.SemiBold : FontWeights.Normal; steps[i].Foreground = (Brush)FindResource(i == page ? "TextBrush" : i < page ? "TextSecondaryBrush" : "TextTertiaryBrush"); } BackButton.Visibility = page is 1 or 2 ? Visibility.Visible : Visibility.Hidden; NextButton.Content = page switch { 2 => "Installieren", 3 => "Fertigstellen", _ => "Weiter" }; NextButton.IsEnabled = page != 1 || AcceptLicense.IsChecked == true; } private void AcceptLicense_Click(object sender, RoutedEventArgs e) => NextButton.IsEnabled = AcceptLicense.IsChecked == true; private void Back_Click(object sender, RoutedEventArgs e) { if (!_busy && _page > 0) ShowPage(_page - 1); } private async void Next_Click(object sender, RoutedEventArgs e) { if (_busy) return; if (_uninstall) { if (_done) { Close(); return; } await RunUninstall(); return; } switch (_page) { case 0: ShowPage(1); break; case 1 when AcceptLicense.IsChecked == true: ShowPage(2); break; case 2: var dir = DirBox.Text.Trim(); if (!Path.IsPathFullyQualified(dir) || dir.IndexOfAny(Path.GetInvalidPathChars()) >= 0) { MessageBox.Show(this, "Bitte einen gültigen Ordner angeben, z. B. C:\\Programme\\DeskCore.", "DeskCore Setup"); return; } await RunInstall(dir); break; case 3: if (LaunchBox.IsChecked == true && _installedExe is not null) Process.Start(new ProcessStartInfo(_installedExe) { UseShellExecute = true }); Close(); break; } } private void ChangeDir_Click(object sender, RoutedEventArgs e) { var dlg = new Microsoft.Win32.OpenFolderDialog { Title = "Installationsordner wählen" }; if (dlg.ShowDialog(this) != true) return; var chosen = dlg.FolderName; // wie bei üblichen Installern: Unterordner "DeskCore" anhängen DirBox.Text = Path.GetFileName(chosen.TrimEnd('\\')).Equals("DeskCore", StringComparison.OrdinalIgnoreCase) ? chosen : Path.Combine(chosen, "DeskCore"); } // ---------- Installation ---------- private async Task RunInstall(string dir) { _busy = true; ShowPage(3); SetButtons(false); var progress = new Progress<(double Value, string Text)>(p => SetProgress(p.Value, p.Text)); bool desktop = DesktopLinkBox.IsChecked == true, autostart = AutostartBox.IsChecked == true; try { await Task.Run(() => Installer.Install(dir, desktop, autostart, progress)); _installedExe = Path.Combine(dir, Installer.ExeName); _done = true; ProgressTitle.Text = "Installation abgeschlossen"; ProgressText.Text = $"DeskCore wurde in {dir} installiert. Du findest es im Startmenü" + (desktop ? " und auf dem Desktop." : "."); DoneText.Text = "Alles bereit!"; DonePanel.Visibility = Visibility.Visible; ShowPage(3); } catch (Exception ex) { ProgressTitle.Text = "Installation fehlgeschlagen"; ProgressText.Text = ex.Message; ProgressText.Foreground = (Brush)FindResource("DangerBrush"); NextButton.Content = "Schließen"; _installedExe = null; } _busy = false; NextButton.IsEnabled = true; CloseButton.IsEnabled = true; BackButton.Visibility = Visibility.Hidden; CancelButton.Visibility = Visibility.Collapsed; } // ---------- Deinstallation ---------- private async void LoadDataInfo() { var root = Installer.DataDirs[0]; if (!Directory.Exists(root)) { DataInfo.Text = "Es wurden keine Kategorien gefunden."; return; } DataInfo.Text = $"Sie liegen in {root}. Größe wird berechnet …"; var size = await Task.Run(Installer.DataSize); DataInfo.Text = $"Sie liegen in {root} ({Installer.FormatSize(size)}) und bleiben dort, falls du DeskCore später wieder installierst."; } private void RemoveDataBox_Click(object sender, RoutedEventArgs e) => RemoveDataWarning.Visibility = RemoveDataBox.IsChecked == true ? Visibility.Visible : Visibility.Collapsed; private async Task RunUninstall() { _busy = true; bool removeData = RemoveDataBox.IsChecked == true; ShowOnly(PageProgress); ProgressTitle.Text = "DeskCore wird entfernt …"; LaunchBox.Visibility = Visibility.Collapsed; SetButtons(false); var progress = new Progress<(double Value, string Text)>(p => SetProgress(p.Value, p.Text)); try { await Task.Run(() => Installer.Uninstall(removeData, progress)); ProgressTitle.Text = "Deinstallation abgeschlossen"; ProgressText.Text = removeData ? "DeskCore, deine Kategorien und Einstellungen wurden entfernt (die Daten liegen im Papierkorb)." : "DeskCore wurde entfernt. Deine Kategorien liegen weiterhin in " + Installer.DataDirs[0] + "."; DoneText.Text = "Fertig"; DonePanel.Visibility = Visibility.Visible; } catch (Exception ex) { ProgressTitle.Text = "Deinstallation fehlgeschlagen"; ProgressText.Text = ex.Message; } _done = true; _busy = false; CloseButton.IsEnabled = true; NextButton.Content = "Schließen"; NextButton.IsEnabled = true; CancelButton.Visibility = Visibility.Collapsed; } // ---------- Helfer ---------- private void SetButtons(bool enabled) { NextButton.IsEnabled = enabled; BackButton.IsEnabled = enabled; CancelButton.IsEnabled = enabled; CloseButton.IsEnabled = enabled; } private void SetProgress(double value, string text) { if (!_done) ProgressText.Text = text; var target = Math.Max(0, ProgressTrack.ActualWidth * value); ProgressFill.BeginAnimation(WidthProperty, new DoubleAnimation(target, TimeSpan.FromMilliseconds(250)) { EasingFunction = new CubicEase() }); } private void Minimize_Click(object sender, RoutedEventArgs e) => WindowState = WindowState.Minimized; private void Cancel_Click(object sender, RoutedEventArgs e) { if (_busy) return; if (!_done && !_uninstall && _page > 0 && MessageBox.Show(this, "Installation wirklich abbrechen?", "DeskCore Setup", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; Close(); } protected override void OnClosing(System.ComponentModel.CancelEventArgs e) { if (_busy) e.Cancel = true; // während der Installation nicht schließen base.OnClosing(e); } }