Desktop-Icons in eigene Kategorien sortieren: Windows-11-Design (hell/dunkel), Desktop-Boxen, automatisches Einsortieren nach Regeln, Rückgängig, Suche, Infobereich mit Tastenkürzel, Sicherung als ZIP und Installer ohne Adminrechte. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
50 lines
1.6 KiB
C#
50 lines
1.6 KiB
C#
using System.Collections.Concurrent;
|
|
using System.IO;
|
|
using System.Windows;
|
|
using System.Windows.Media;
|
|
|
|
namespace DeskCore;
|
|
|
|
/// <summary>Lädt Icons auf einem eigenen STA-Thread (Shell-COM braucht STA) und cached sie.</summary>
|
|
public static class IconLoader
|
|
{
|
|
private static readonly ConcurrentDictionary<string, ImageSource?> _cache = new(StringComparer.OrdinalIgnoreCase);
|
|
private static readonly BlockingCollection<(IconItem Item, int Size)> _queue = new();
|
|
|
|
static IconLoader()
|
|
{
|
|
var t = new Thread(Work) { IsBackground = true, Name = "IconLoader" };
|
|
t.SetApartmentState(ApartmentState.STA);
|
|
t.Start();
|
|
}
|
|
|
|
private static string Key(string path, int size)
|
|
{
|
|
DateTime stamp;
|
|
try { stamp = File.GetLastWriteTimeUtc(path); } catch { stamp = default; }
|
|
return $"{size}|{stamp.Ticks}|{path}";
|
|
}
|
|
|
|
/// <summary>Setzt das Icon sofort aus dem Cache oder lädt es im Hintergrund nach.</summary>
|
|
public static void Load(IconItem item, int size)
|
|
{
|
|
if (_cache.TryGetValue(Key(item.Path, size), out var icon)) item.Icon = icon;
|
|
else _queue.Add((item, size));
|
|
}
|
|
|
|
private static void Work()
|
|
{
|
|
foreach (var (item, size) in _queue.GetConsumingEnumerable())
|
|
{
|
|
var key = Key(item.Path, size);
|
|
if (!_cache.TryGetValue(key, out var icon))
|
|
{
|
|
icon = ShellIcon.Get(item.Path, size);
|
|
_cache[key] = icon;
|
|
}
|
|
var result = icon;
|
|
Application.Current?.Dispatcher.BeginInvoke(() => item.Icon = result);
|
|
}
|
|
}
|
|
}
|