Fix title bar icon missing in single-file published builds

The title bar Image used Source="ms-appx:///Assets/Square44x44Logo.scale-200.png".
That resolves fine in a normal build (Assets/ and AmiReel.pri sit next to the exe),
but a single-file self-contained publish (IncludeAllContentForSelfExtract=true)
bundles Content items into the exe in a way ms-appx:// can no longer resolve at
runtime, leaving the title bar icon blank — reproduced with the actual
publish-win-x64.ps1 output, confirmed fixed the same way.

Load the icon from a plain embedded resource instead (same mechanism already
used for ffmpeg.exe/ffprobe.exe): the PNG is embedded via
<EmbeddedResource LogicalName="AmiReel.Assets.TitleBarIcon.png">, and
MainWindow loads it at startup via GetManifestResourceStream + BitmapImage.
SetSourceAsync. This bypasses the ms-appx/MRT resource pipeline entirely, so
it behaves identically in dotnet build, dotnet run, and a single-file publish.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-13 16:01:20 +02:00
parent c412469773
commit 8f27aee11a
3 changed files with 34 additions and 1 deletions
+28
View File
@@ -2,9 +2,12 @@ using Microsoft.UI;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Imaging;
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Graphics;
using Windows.UI;
using WinRT.Interop;
@@ -36,6 +39,7 @@ public sealed partial class MainWindow : Window
AppWindow.SetIcon(executablePath);
SetDefaultSizeAndPosition();
LoadTitleBarIcon();
// Navigate the root frame to the main page on startup.
RootFrame.Navigate(typeof(MainPage));
@@ -43,6 +47,30 @@ public sealed partial class MainWindow : Window
AppWindow.Closing += AppWindow_Closing;
}
/// <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
/// way the ms-appx resource pipeline can no longer resolve at runtime, leaving the title bar
/// blank; a plain embedded resource stream works the same in every publish mode.
/// </summary>
private async void LoadTitleBarIcon()
{
try
{
Assembly assembly = Assembly.GetExecutingAssembly();
using Stream? stream = assembly.GetManifestResourceStream("AmiReel.Assets.TitleBarIcon.png");
if (stream is null) return;
BitmapImage bitmap = new();
await bitmap.SetSourceAsync(stream.AsRandomAccessStream());
TitleBarIcon.Source = bitmap;
}
catch
{
// Non-critical: the title bar simply shows no icon if this fails.
}
}
private void SetDefaultSizeAndPosition()
{
const int DefaultWidth = 1280;