Upload via GUI (180 Dateien)
This commit is contained in:
+191
-128
@@ -1,128 +1,191 @@
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
|
||||
namespace DeskCore;
|
||||
|
||||
public partial class App : Application
|
||||
{
|
||||
private const string MutexName = "DeskCore.Instanz";
|
||||
private const string ShowEventName = "DeskCore.Anzeigen";
|
||||
|
||||
public static MainWindow? Win { get; private set; }
|
||||
public static Tray? TrayIcon { get; private set; }
|
||||
public static bool Quitting { get; private set; }
|
||||
|
||||
private static Hotkey? _hotkey;
|
||||
private static Watcher? _watcher;
|
||||
private Mutex? _mutex;
|
||||
private EventWaitHandle? _showEvent;
|
||||
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
{
|
||||
// Nur eine Instanz: eine zweite holt einfach das vorhandene Fenster nach vorne
|
||||
_mutex = new Mutex(true, MutexName, out bool first);
|
||||
if (!first)
|
||||
{
|
||||
try { EventWaitHandle.OpenExisting(ShowEventName).Set(); } catch { }
|
||||
Shutdown();
|
||||
return;
|
||||
}
|
||||
Migration.Run(); // alte "Desktop Sortierer"-Ordner übernehmen – vor allem anderen
|
||||
_showEvent = new EventWaitHandle(false, EventResetMode.AutoReset, ShowEventName);
|
||||
new Thread(() =>
|
||||
{
|
||||
while (_showEvent.WaitOne())
|
||||
Dispatcher.BeginInvoke(() => Win?.ShowFromBackground());
|
||||
}) { IsBackground = true, Name = "ShowListener" }.Start();
|
||||
|
||||
DispatcherUnhandledException += (_, args) =>
|
||||
{
|
||||
var log = Path.Combine(Storage.Root, "fehler.log");
|
||||
try { File.AppendAllText(log, $"[{DateTime.Now}] {args.Exception}\n\n"); } catch { }
|
||||
MessageBox.Show($"Unerwarteter Fehler:\n\n{args.Exception.Message}\n\nDetails: {log}", "DeskCore",
|
||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
args.Handled = true;
|
||||
};
|
||||
|
||||
base.OnStartup(e);
|
||||
ShutdownMode = ShutdownMode.OnExplicitShutdown;
|
||||
|
||||
Storage.FlushHolding(); // Reste eines Absturzes in den Papierkorb
|
||||
Theme.Init();
|
||||
Theme.Changed += FenceManager.RefreshAll;
|
||||
|
||||
Win = new MainWindow();
|
||||
MainWindow = Win;
|
||||
var hwnd = new WindowInteropHelper(Win).EnsureHandle();
|
||||
|
||||
_hotkey = new Hotkey(hwnd);
|
||||
_hotkey.Pressed += () => Win.ToggleFromHotkey();
|
||||
ApplyHotkey();
|
||||
|
||||
TrayIcon = new Tray();
|
||||
TrayIcon.Clicked += () => Win.ShowFromBackground();
|
||||
TrayIcon.BalloonClicked += () => Win.ShowFromBackground();
|
||||
TrayIcon.MenuRequested += () => Win.ShowTrayMenu();
|
||||
ApplyTray();
|
||||
|
||||
_watcher = new Watcher(Dispatcher);
|
||||
_watcher.Changed += () =>
|
||||
{
|
||||
Win.OnStorageChanged();
|
||||
FenceManager.RefreshAll();
|
||||
};
|
||||
_watcher.NewOnDesktop += Win.AutoSortNew;
|
||||
|
||||
Autostart.RefreshPath();
|
||||
|
||||
bool minimized = e.Args.Contains("--minimized", StringComparer.OrdinalIgnoreCase);
|
||||
if (!minimized || !AppSettings.Current.TrayEnabled) Win.Show();
|
||||
FenceManager.Sync();
|
||||
|
||||
// Bildschirm abgesteckt/Auflösung geändert → Fenster und Boxen wieder in den sichtbaren Bereich holen
|
||||
Microsoft.Win32.SystemEvents.DisplaySettingsChanged += (_, _) => Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
Win.EnsureOnScreen();
|
||||
FenceManager.EnsureOnScreen();
|
||||
});
|
||||
|
||||
Win.CheckForUpdatesOnStartup();
|
||||
}
|
||||
|
||||
/// <summary>Tastenkürzel neu registrieren. false = von anderem Programm belegt.</summary>
|
||||
public static bool ApplyHotkey()
|
||||
{
|
||||
if (_hotkey is null) return false;
|
||||
var s = AppSettings.Current;
|
||||
if (!s.HotkeyEnabled) { _hotkey.Unregister(); return true; }
|
||||
return _hotkey.Register(s.HotkeyModifiers, s.HotkeyKey);
|
||||
}
|
||||
|
||||
public static void ApplyTray()
|
||||
{
|
||||
if (TrayIcon is not null) TrayIcon.Visible = AppSettings.Current.TrayEnabled;
|
||||
}
|
||||
|
||||
public static void Quit()
|
||||
{
|
||||
if (Quitting) return;
|
||||
Quitting = true;
|
||||
Win?.CancelBusyAndWait(); // z. B. große Kopie abbrechen, halbe Dateien aufräumen
|
||||
Win?.SavePlacement();
|
||||
Win?.Undo.FlushAll();
|
||||
FenceManager.CloseAll();
|
||||
_watcher?.Dispose();
|
||||
_hotkey?.Dispose();
|
||||
TrayIcon?.Dispose();
|
||||
Win?.Close();
|
||||
Current.Shutdown();
|
||||
}
|
||||
|
||||
protected override void OnExit(ExitEventArgs e)
|
||||
{
|
||||
TrayIcon?.Dispose();
|
||||
_mutex?.Dispose();
|
||||
base.OnExit(e);
|
||||
}
|
||||
}
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
|
||||
namespace DeskCore;
|
||||
|
||||
public partial class App : Application
|
||||
{
|
||||
private const string MutexName = "DeskCore.Instanz";
|
||||
|
||||
public static MainWindow? Win { get; private set; }
|
||||
public static Tray? TrayIcon { get; private set; }
|
||||
public static bool Quitting { get; private set; }
|
||||
|
||||
private static Hotkey? _hotkey;
|
||||
private static Hotkey? _peekHotkey;
|
||||
private static Hotkey? _pagePrev, _pageNext;
|
||||
private static System.Windows.Threading.DispatcherTimer? _desktopTimer;
|
||||
private static Watcher? _watcher;
|
||||
private Mutex? _mutex;
|
||||
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
{
|
||||
// Nur eine Instanz: weitere Aufrufe reichen ihren Befehl (oder "Fenster zeigen") an die laufende weiter
|
||||
_mutex = new Mutex(true, MutexName, out bool first);
|
||||
if (!first)
|
||||
{
|
||||
Commands.Send(e.Args);
|
||||
Shutdown();
|
||||
return;
|
||||
}
|
||||
Migration.Run(); // alte "Desktop Sortierer"-Ordner übernehmen – vor allem anderen
|
||||
Commands.Listen(args => Dispatcher.BeginInvoke(() => HandleCommand(args)));
|
||||
|
||||
DispatcherUnhandledException += (_, args) =>
|
||||
{
|
||||
var log = Path.Combine(Storage.Root, "fehler.log");
|
||||
try { File.AppendAllText(log, $"[{DateTime.Now}] {args.Exception}\n\n"); } catch { }
|
||||
MessageBox.Show($"Unerwarteter Fehler:\n\n{args.Exception.Message}\n\nDetails: {log}", "DeskCore",
|
||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
args.Handled = true;
|
||||
};
|
||||
|
||||
base.OnStartup(e);
|
||||
ShutdownMode = ShutdownMode.OnExplicitShutdown;
|
||||
|
||||
Storage.FlushHolding(); // Reste eines Absturzes in den Papierkorb
|
||||
Theme.Init();
|
||||
Theme.Changed += FenceManager.RefreshAll;
|
||||
|
||||
Win = new MainWindow();
|
||||
MainWindow = Win;
|
||||
var hwnd = new WindowInteropHelper(Win).EnsureHandle();
|
||||
|
||||
_hotkey = new Hotkey(hwnd);
|
||||
_hotkey.Pressed += () => Win.ToggleFromHotkey();
|
||||
ApplyHotkey();
|
||||
_peekHotkey = new Hotkey(hwnd, 0xB002);
|
||||
_peekHotkey.Pressed += FenceManager.TogglePeek;
|
||||
ApplyPeekHotkey();
|
||||
// Desktop-Seiten: Win + Alt + Pfeil links/rechts
|
||||
_pagePrev = new Hotkey(hwnd, 0xB003);
|
||||
_pagePrev.Pressed += () => FenceManager.NextPage(-1);
|
||||
_pagePrev.Register(Hotkey.ModWin | Hotkey.ModAlt, 0x25);
|
||||
_pageNext = new Hotkey(hwnd, 0xB004);
|
||||
_pageNext.Pressed += () => FenceManager.NextPage(1);
|
||||
_pageNext.Register(Hotkey.ModWin | Hotkey.ModAlt, 0x27);
|
||||
|
||||
TrayIcon = new Tray();
|
||||
TrayIcon.Clicked += () => Win.ShowFromBackground();
|
||||
TrayIcon.BalloonClicked += () => Win.ShowFromBackground();
|
||||
TrayIcon.MenuRequested += () => Win.ShowTrayMenu();
|
||||
ApplyTray();
|
||||
|
||||
_watcher = new Watcher(Dispatcher);
|
||||
_watcher.Changed += () =>
|
||||
{
|
||||
Win.OnStorageChanged();
|
||||
FenceManager.RefreshAll();
|
||||
Win.ScheduleDeadShortcutScan(); // z. B. Deinstallation hat die Desktop-Verknüpfung entfernt
|
||||
};
|
||||
_watcher.NewOnDesktop += Win.AutoSortNew;
|
||||
|
||||
Autostart.RefreshPath();
|
||||
|
||||
// Mit einem Befehl gestartet (z. B. Start-Gruppe per Desktop-Verknüpfung)? Dann ohne Fenster.
|
||||
if (Commands.WantsWindow(e.Args) || !AppSettings.Current.TrayEnabled) Win.Show();
|
||||
FenceManager.Sync();
|
||||
|
||||
// Bildschirm abgesteckt/Auflösung geändert → Fenster und Boxen wieder in den sichtbaren Bereich holen
|
||||
Microsoft.Win32.SystemEvents.DisplaySettingsChanged += (_, _) => Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
Win.EnsureOnScreen();
|
||||
FenceManager.OnDisplayChanged();
|
||||
});
|
||||
|
||||
Win.CheckForUpdatesOnStartup();
|
||||
if (!Commands.WantsWindow(e.Args)) Dispatcher.BeginInvoke(() => HandleCommand(e.Args));
|
||||
Win.StartDeadShortcutWatch();
|
||||
DesktopToggle.Apply();
|
||||
|
||||
// Positionen der Desktop-Icons regelmäßig lesen (für Aufziehen, Doppelklick und die Icon-Tönung)
|
||||
_desktopTimer = new System.Windows.Threading.DispatcherTimer { Interval = TimeSpan.FromSeconds(2) };
|
||||
_desktopTimer.Tick += (_, _) => RefreshDesktopIcons();
|
||||
_desktopTimer.Start();
|
||||
RefreshDesktopIcons();
|
||||
}
|
||||
|
||||
private static void RefreshDesktopIcons()
|
||||
{
|
||||
var s = AppSettings.Current;
|
||||
if (Quitting) return;
|
||||
// Nur lesen, wenn eine Funktion die Positionen braucht
|
||||
if (s.DesktopTint is null && !s.DrawFences && !s.QuickHide) return;
|
||||
try { DesktopIcons.RefreshCache(); } catch { /* Explorer gerade neu gestartet o. Ä. */ }
|
||||
DesktopTint.Refresh();
|
||||
}
|
||||
|
||||
/// <summary>Befehl von der Befehlszeile oder einem weiteren Aufruf ausführen.</summary>
|
||||
private static void HandleCommand(string[] args)
|
||||
{
|
||||
if (Win is null || Quitting) return;
|
||||
if (Commands.Value(args, "--launch") is { } group) Win.LaunchGroupByName(group);
|
||||
else if (Commands.Value(args, "--snapshot") is { } snap) Win.RestoreSnapshotByName(snap);
|
||||
else if (Commands.Has(args, "--toggle-desktop")) DesktopToggle.Toggle();
|
||||
else if (Commands.Has(args, "--peek")) FenceManager.TogglePeek();
|
||||
else if (Commands.Value(args, "--page") is { } page) SwitchPageByName(page);
|
||||
else if (Commands.WantsWindow(args)) Win.ShowFromBackground();
|
||||
}
|
||||
|
||||
/// <summary>DeskCore.exe --page "Name" oder --page 2.</summary>
|
||||
private static void SwitchPageByName(string page)
|
||||
{
|
||||
var pages = AppSettings.Current.Pages;
|
||||
int i = pages.FindIndex(p => string.Equals(p, page, StringComparison.OrdinalIgnoreCase));
|
||||
if (i < 0 && int.TryParse(page, out var n)) i = n - 1;
|
||||
if (i >= 0 && i < pages.Count) FenceManager.SwitchPage(i);
|
||||
else TrayIcon?.Notify("Seite nicht gefunden", $"Es gibt keine Desktop-Seite „{page}“.");
|
||||
}
|
||||
|
||||
/// <summary>Tastenkürzel neu registrieren. false = von anderem Programm belegt.</summary>
|
||||
public static bool ApplyHotkey()
|
||||
{
|
||||
if (_hotkey is null) return false;
|
||||
var s = AppSettings.Current;
|
||||
if (!s.HotkeyEnabled) { _hotkey.Unregister(); return true; }
|
||||
return _hotkey.Register(s.HotkeyModifiers, s.HotkeyKey);
|
||||
}
|
||||
|
||||
/// <summary>Peek-Kürzel neu registrieren. false = von anderem Programm belegt.</summary>
|
||||
public static bool ApplyPeekHotkey()
|
||||
{
|
||||
if (_peekHotkey is null) return false;
|
||||
var s = AppSettings.Current;
|
||||
if (!s.PeekEnabled) { _peekHotkey.Unregister(); return true; }
|
||||
return _peekHotkey.Register(s.PeekModifiers, s.PeekKey);
|
||||
}
|
||||
|
||||
public static void ApplyTray()
|
||||
{
|
||||
if (TrayIcon is not null) TrayIcon.Visible = AppSettings.Current.TrayEnabled;
|
||||
}
|
||||
|
||||
public static void Quit()
|
||||
{
|
||||
if (Quitting) return;
|
||||
Quitting = true;
|
||||
Win?.CancelBusyAndWait(); // z. B. große Kopie abbrechen, halbe Dateien aufräumen
|
||||
Win?.SavePlacement();
|
||||
_desktopTimer?.Stop();
|
||||
DesktopToggle.Stop();
|
||||
DesktopToggle.RestoreOnExit();
|
||||
_peekHotkey?.Dispose();
|
||||
_pagePrev?.Dispose();
|
||||
_pageNext?.Dispose();
|
||||
Win?.Undo.FlushAll();
|
||||
FenceManager.CloseAll();
|
||||
_watcher?.Dispose();
|
||||
_hotkey?.Dispose();
|
||||
TrayIcon?.Dispose();
|
||||
Win?.Close();
|
||||
Current.Shutdown();
|
||||
}
|
||||
|
||||
protected override void OnExit(ExitEventArgs e)
|
||||
{
|
||||
TrayIcon?.Dispose();
|
||||
_mutex?.Dispose();
|
||||
base.OnExit(e);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user