Fix missing taskbar/Alt+Tab icon

AppWindow.SetIcon(executablePath) was passing the .exe's own path, but that
API requires an actual .ico file path — passing an .exe silently does
nothing, so the window fell back to a generic placeholder icon in the
taskbar and Alt+Tab (the custom title bar icon fixed earlier is a separate,
XAML-drawn Image and was unaffected).

Embed branding/AmiReel.ico as a resource, extract it once to
%LOCALAPPDATA%\AmiReel\app-icon.ico on startup, and call
AppWindow.SetIcon() with that file path instead. Verified via WM_GETICON
against the running window's HWND that both the big and small icons now
resolve to the real AmiReel logo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-13 16:38:12 +02:00
parent fc02cd9602
commit f1f1be778b
2 changed files with 37 additions and 4 deletions
+33 -4
View File
@@ -34,10 +34,7 @@ public sealed partial class MainWindow : Window
ExtendsContentIntoTitleBar = true;
SetTitleBar(AppTitleBar);
string? executablePath = Environment.ProcessPath;
if (!string.IsNullOrWhiteSpace(executablePath) && File.Exists(executablePath))
AppWindow.SetIcon(executablePath);
SetWindowIcon();
SetDefaultSizeAndPosition();
LoadTitleBarIcon();
@@ -47,6 +44,38 @@ public sealed partial class MainWindow : Window
AppWindow.Closing += AppWindow_Closing;
}
/// <summary>
/// Sets the window's taskbar/Alt+Tab icon. <see cref="AppWindow.SetIcon(string)"/> requires an
/// actual .ico file path (an .exe path is silently ignored), so the embedded .ico is extracted
/// once to a stable file under %LOCALAPPDATA% and that path is used instead.
/// </summary>
private void SetWindowIcon()
{
try
{
string iconPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"AmiReel", "app-icon.ico");
if (!File.Exists(iconPath))
{
Directory.CreateDirectory(Path.GetDirectoryName(iconPath)!);
Assembly assembly = Assembly.GetExecutingAssembly();
using Stream? resource = assembly.GetManifestResourceStream("AmiReel.Assets.AppIcon.ico");
if (resource is null) return;
using FileStream file = File.Create(iconPath);
resource.CopyTo(file);
}
AppWindow.SetIcon(iconPath);
}
catch
{
// Non-critical: the window simply keeps whatever default icon Windows assigned.
}
}
/// <summary>
/// Loads the title bar icon from an embedded resource instead of an "ms-appx:///Assets/..."
/// URI. A single-file self-contained publish bundles Content/Assets items into the exe in a