From 767f640187fab9dd88988670aaf00aa7fefc67bd Mon Sep 17 00:00:00 2001 From: Tim Haasdyk Date: Tue, 18 Aug 2026 14:31:08 +0200 Subject: [PATCH] Log Windows updating the FW Lite MSIX package Windows stages an .appinstaller update on its own schedule and registers it at activation, force-terminating a running instance to do so. None of that reaches our log today, so a forced shutdown looks like an unexplained restart. Subscribe to PackageCatalog.PackageUpdating for our own package and log target version, progress and errors. Diagnostics only, no behaviour change. Co-Authored-By: Claude Opus 5 --- .../Platforms/Windows/PackageUpdateLogger.cs | 59 +++++++++++++++++++ .../Platforms/Windows/WindowsKernel.cs | 1 + 2 files changed, 60 insertions(+) create mode 100644 backend/FwLite/FwLiteMaui/Platforms/Windows/PackageUpdateLogger.cs diff --git a/backend/FwLite/FwLiteMaui/Platforms/Windows/PackageUpdateLogger.cs b/backend/FwLite/FwLiteMaui/Platforms/Windows/PackageUpdateLogger.cs new file mode 100644 index 0000000000..26f4611a28 --- /dev/null +++ b/backend/FwLite/FwLiteMaui/Platforms/Windows/PackageUpdateLogger.cs @@ -0,0 +1,59 @@ +using Windows.ApplicationModel; +using Microsoft.Extensions.Logging; + +namespace FwLiteMaui; + +/// +/// Logs Windows updating our own MSIX package. The OS stages an update on its own schedule and registers it +/// at activation, force-terminating this process if it's running, which otherwise leaves nothing in our log. +/// +public class PackageUpdateLogger(ILogger logger) : IMauiInitializeService +{ + //field, not a local: the subscription stops firing once the catalog is collected + private PackageCatalog? _packageCatalog; + private int _loggedProgressDecile = -1; + + public void Initialize(IServiceProvider services) + { + try + { + _packageCatalog = PackageCatalog.OpenForCurrentPackage(); + } + catch (Exception e) + { + logger.LogWarning(e, "Unable to open the package catalog, OS package updates won't be logged"); + return; + } + + _packageCatalog.PackageUpdating += OnPackageUpdating; + } + + private void OnPackageUpdating(PackageCatalog sender, PackageUpdatingEventArgs args) + { + var version = FormatVersion(args.TargetPackage); + if (args.ErrorCode is { HResult: not 0 }) + { + logger.LogError(args.ErrorCode, "Windows failed to update this app to {TargetVersion}", version); + return; + } + + if (args.IsComplete) + { + logger.LogInformation("Windows finished updating this app to {TargetVersion}", version); + return; + } + + //progress fires often, so only log each 10% step + var decile = (int)(args.Progress / 10); + if (decile == _loggedProgressDecile) return; + _loggedProgressDecile = decile; + logger.LogInformation("Windows is updating this app to {TargetVersion}: {Progress}%", version, args.Progress); + } + + private static string FormatVersion(Package? package) + { + if (package is null) return "unknown"; + var version = package.Id.Version; + return $"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}"; + } +} diff --git a/backend/FwLite/FwLiteMaui/Platforms/Windows/WindowsKernel.cs b/backend/FwLite/FwLiteMaui/Platforms/Windows/WindowsKernel.cs index df5af42166..7a46199d36 100644 --- a/backend/FwLite/FwLiteMaui/Platforms/Windows/WindowsKernel.cs +++ b/backend/FwLite/FwLiteMaui/Platforms/Windows/WindowsKernel.cs @@ -24,6 +24,7 @@ public static void AddFwLiteWindows(this IServiceCollection services, IHostEnvir if (!FwLiteMauiKernel.IsPortableApp) { services.AddSingleton(); + services.AddSingleton(); } services.Configure(config =>