dragon-iso/src/TeamsISO.App.WinUI.Probe/Program.cs
Zac Gaetano 166e7d6e6a
Some checks failed
CI / build-and-test (push) Has been cancelled
build(winui3): switch to WindowsAppSDK 1.8 + add diagnostic probe
Two big findings from a custom MddBootstrapInitialize2 P/Invoke probe
this session:

1. The original WinUI 3 activation failure ("this application could not
   be started") was MDD_E_BOOTSTRAP_INITIALIZE_DDLM_NOT_FOUND (HR
   0x80670016). The framework package Microsoft.WindowsAppRuntime.1.6
   was installed, but the Dynamic Dependency Lifetime Manager sibling
   (MicrosoftCorporationII.WinAppRuntime.Main.1.6) wasn't. This machine
   has Main.1.5 and Main.1.8 packages but no Main.1.6, so bootstrap for
   1.6 fails.

2. Switching the WindowsAppSDK NuGet to 1.8.250916003 + the bootstrap
   major.minor to 0x00010008 in Program.cs gets past activation. The
   .exe now launches and Bootstrap.TryInitialize returns S_OK. The 1.8
   DDLM is present and the runtime spins up.

Also lands `src/TeamsISO.App.WinUI.Probe/`, a tiny console diagnostic
that calls MddBootstrapInitialize2 directly via P/Invoke (bypassing the
full WindowsAppSDK NuGet to avoid the MRT/PRI MSBuild tasks that need
VS's AppxPackage tooling installed). The probe prints the HResult and a
human-readable description; use it to triage WindowsAppSDK activation
on any deployment target:

  dotnet run --project src/TeamsISO.App.WinUI.Probe

A SECOND ISSUE surfaces after activation: the .exe crashes 1 second
after launch with 0xC000027B inside Microsoft.UI.Xaml.dll, sub-code
0x802b000a (XAML_E_PARSER_GENERAL_ERROR). The participants ItemsRepeater
with {Binding ...} markup is suspect (WinUI 3 prefers x:Bind with
x:DataType, and Visibility="{Binding bool}" needs a converter). The
ItemsRepeater is stubbed out to a plain "Participants list renders here"
TextBlock placeholder for now; same crash recurs, so the XAML issue is
elsewhere — likely in Controls.xaml (one of CharacterSpacing /
TextCaption / etc. unsupported), in App.xaml's MergedDictionary chain,
or in MainWindow.xaml's Storyboard target.

Triaging the XAML parse error is the next session's first action. The
sub-code 0x802b000a will help (search WindowsAppSDK source for the
matching XAML parser error). The migration plan in
docs/superpowers/plans/2026-05-12-winui3-migration.md is updated.

Build remains clean.
2026-05-13 00:39:43 -04:00

142 lines
6.2 KiB
C#

using System;
using System.Runtime.InteropServices;
namespace TeamsISO.App.WinUI.Probe;
/// <summary>
/// Tiny diagnostic console — calls the native MddBootstrapInitialize2
/// export from Microsoft.WindowsAppRuntime.Bootstrap.dll directly and
/// reports the HResult.
///
/// Use to isolate whether the WinUI 3 activation blocker is:
/// (a) Bootstrap DLL load — DllNotFoundException at the P/Invoke call
/// (b) Framework package resolution — Bootstrap returns non-S_OK HR
/// (c) Downstream — Bootstrap succeeds, the WinUI 3 .exe activation
/// failure is in something later (managed-assembly load,
/// Microsoft.WinUI.dll native imports, etc.)
/// </summary>
internal static class Program
{
/// <summary>WindowsAppSDK target major/minor.</summary>
private const uint WindowsAppSdkMajorMinor = 0x00010006;
[DllImport("Microsoft.WindowsAppRuntime.Bootstrap.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
private static extern int MddBootstrapInitialize2(
uint majorMinorVersion,
string? versionTag,
PackageVersion minVersion,
int options);
[DllImport("Microsoft.WindowsAppRuntime.Bootstrap.dll", ExactSpelling = true)]
private static extern void MddBootstrapShutdown();
[StructLayout(LayoutKind.Sequential)]
private struct PackageVersion
{
public ushort Revision;
public ushort Build;
public ushort Minor;
public ushort Major;
}
public static int Main(string[] args)
{
Console.WriteLine("TeamsISO WinUI 3 bootstrap probe");
Console.WriteLine("───────────────────────────────────────────");
Console.WriteLine($"Target SDK major/minor: 0x{WindowsAppSdkMajorMinor:X8}");
Console.WriteLine();
try
{
// Try with both null and "" for versionTag; report both.
var minVersion = new PackageVersion();
Console.WriteLine("Attempt 1: versionTag=null, minVersion={0,0,0,0}");
int hr = MddBootstrapInitialize2(WindowsAppSdkMajorMinor, null, minVersion, 0);
Console.WriteLine($" HR=0x{hr:X8} ({Describe(hr)})");
if (hr != 0)
{
Console.WriteLine();
Console.WriteLine("Attempt 2: versionTag=\"\", minVersion={0,0,0,0}");
hr = MddBootstrapInitialize2(WindowsAppSdkMajorMinor, "", minVersion, 0);
Console.WriteLine($" HR=0x{hr:X8} ({Describe(hr)})");
}
if (hr != 0)
{
Console.WriteLine();
Console.WriteLine("Attempt 3: versionTag=\"\", options=1 (DoNotShowDialog)");
hr = MddBootstrapInitialize2(WindowsAppSdkMajorMinor, "", minVersion, 1);
Console.WriteLine($" HR=0x{hr:X8} ({Describe(hr)})");
}
if (hr == 0)
{
Console.WriteLine();
Console.WriteLine("Bootstrap succeeded.");
Console.WriteLine("The WinUI 3 .exe activation failure is NOT in the bootstrap.");
Console.WriteLine("Suspect: downstream managed-assembly load (Microsoft.WinUI.dll");
Console.WriteLine("native imports during JIT).");
MddBootstrapShutdown();
}
else
{
Console.WriteLine();
Console.WriteLine("Bootstrap failed. Decode the HResult:");
DescribeHResult(hr);
}
}
catch (DllNotFoundException ex)
{
Console.WriteLine($"DllNotFoundException: {ex.Message}");
Console.WriteLine();
Console.WriteLine("Microsoft.WindowsAppRuntime.Bootstrap.dll couldn't be located by");
Console.WriteLine("the loader. Check that the file is alongside the .exe and that the");
Console.WriteLine("process architecture matches (x64 .exe loads x64 DLLs).");
}
catch (Exception ex)
{
Console.WriteLine($"Unexpected: {ex.GetType().Name}: {ex.Message}");
}
Console.WriteLine();
Console.WriteLine("Press any key to exit.");
Console.ReadKey(true);
return 0;
}
private static string Describe(int hr) => hr switch
{
0 => "S_OK",
unchecked((int)0x80073B17) => "ERROR_INSTALL_PACKAGE_NOT_FOUND",
unchecked((int)0x80073B19) => "ERROR_PACKAGES_REPUTATION_CHECK_FAILED",
unchecked((int)0x80004005) => "E_FAIL",
unchecked((int)0x80670016) => "MDD_E_BOOTSTRAP_INITIALIZE_DDLM_NOT_FOUND",
unchecked((int)0x80670017) => "MDD_E_BOOTSTRAP_INITIALIZE_LIFECYCLE_MANAGER_FAILURE",
_ => "(unknown HR)",
};
private static void DescribeHResult(int hr)
{
var description = (uint)hr switch
{
0x80670016 =>
"DDLM (Dynamic Dependency Lifetime Manager) for this WindowsAppSDK major.minor\n" +
" is NOT installed on this machine. The framework package (Microsoft.WindowsApp\n" +
" Runtime.1.6) may be present but its DDLM sibling — MicrosoftCorporationII.\n" +
" WinAppRuntime.Main.1.6 — is missing. Run \"Get-AppxPackage | Where Name -like\n" +
" '*WinAppRuntime.Main*'\" to see which versions have DDLM coverage. Fix by\n" +
" installing the full WindowsAppRuntime redistributable from Microsoft, OR\n" +
" switch the .csproj to a major.minor whose Main package IS installed.",
0x80670017 =>
"Lifecycle manager start failed. The DDLM is installed but couldn't be activated.\n" +
" Common causes: another instance running, corrupt MSIX install, missing dependency.",
0x80073B17 => "Framework package not found. Install Microsoft.WindowsAppRuntime.<x.y>.",
0x80073B18 => "Framework package version mismatch.",
0x80073B19 => "Framework package not present for current user.",
0x80073B26 => "Framework package architecture mismatch.",
_ => $"Unknown HResult. Look up in WindowsAppSDK source BootstrapErrorCodes.h.",
};
Console.WriteLine($" {description}");
}
}