Skip to content

[Keyboard Manager] Build the WinUI 3 editor self-contained to fix launch crash (0xC0000409) - #49524

Merged
moooyo merged 1 commit into
mainfrom
yuleng/keyboardmanager/winui3-editor-selfcontained/1
Jul 28, 2026
Merged

[Keyboard Manager] Build the WinUI 3 editor self-contained to fix launch crash (0xC0000409)#49524
moooyo merged 1 commit into
mainfrom
yuleng/keyboardmanager/winui3-editor-selfcontained/1

Conversation

@moooyo

@moooyo moooyo commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary of the Pull Request

PowerToys.KeyboardManagerEditorUI.exe fail-fasts with 0xC0000409 (STATUS_STACK_BUFFER_OVERRUN) during MainWindow construction, so the new Keyboard Manager editor never opens. KeyboardManagerEditorUI.csproj was the only WinUI 3 executable in the repo missing <WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>, so it was built framework-package-dependent and mixed two Windows App SDK provenances in one process.

PR Checklist

Detailed Description of the Pull Request / Additional comments

Root cause

The reporter's WinDbg capture shows a first-chance Core::ApiException carrying 0x800704DF (ERROR_ALREADY_INITIALIZED):

MainWindow.SetTitleBar
-> Microsoft.UI.Xaml.Window.set_ExtendsContentIntoTitleBar
-> Microsoft.UI.Input!InputNonClientPointerSourceWinRTStatics::GetForWindowIdHelper
-> Microsoft.UI.Windowing.Core!RegisterWindowFeature
-> Core::NamedApiObject::Init
-> Core::ApiException

ExtendsContentIntoTitleBar is the site, not the cause — it is simply the first user statement that crosses XAML -> Windowing -> Input.

microsoft.windowsappsdk.foundation/*/buildTransitive/Microsoft.WindowsAppSDK.BootstrapCommon.targets turns the bootstrapper on precisely when this project's shape is hit:

<PropertyGroup Condition="'$(WindowsAppSdkBootstrapInitialize)'=='' and '$(WindowsAppSDKSelfContained)'!='true' and '$(WindowsPackageType)'=='None' and ('$(OutputType)'=='Exe' or '$(OutputType)'=='Winexe')">
    <WindowsAppSdkBootstrapInitialize>true</WindowsAppSdkBootstrapInitialize>
</PropertyGroup>

That compiles in MddBootstrapAutoInitializer.cs, which joins the machine-wide Microsoft.WindowsAppRuntime MSIX framework package to the process package graph before Main. Meanwhile the exe's own directory — WinUI3Apps — is first in the Win32 DLL search order and already contains a complete app-local Windows App SDK payload, deployed there by the other 14 self-contained apps. One process, two Windows App SDK provenances, and the one-time feature-type registration in Microsoft.UI.Input collides.

The omission was easy to miss: the project imports src\Common.SelfContained.props, whose name suggests it covers this — but it only sets the .NET <SelfContained> property, which is unrelated.

This also explains why the reporter could not shake it off: the framework package is machine state, so uninstall/reinstall and wiping %LOCALAPPDATA%\Microsoft\PowerToys change nothing. The classic C++ editor is unaffected because it uses WinUI 2 XAML Islands and ships no Windows App SDK at all. PowerToys.Settings.exe ran healthily in the same elevated session on the same day while doing strictly more title-bar work (it sets ExtendsContentIntoTitleBar twice and drives InputNonClientPointerSource.GetForWindowId on every SizeChanged) — because it is self-contained.

Two additional defects fixed

Both were found while investigating why the crash left no diagnostics at all:

  1. App.xaml.cs initialized the logger via fire-and-forget Task.Run — the only one of ~30 Logger.InitializeLogger call sites in the repo to do so. That races window creation, and Logger has no buffering or replay (Trace.WriteLine straight through, listener attached in InitializeLogger), so anything logged before the listener is attached is lost permanently. This is why the user's bug report bundle contains a WinUI3Editor log for the day it worked and no log file at all for the day it crashed. Made synchronous, ordered to match FileLocksmithXAML/App.xaml.cs, plus a log line before the window is constructed.

  2. MainWindow never called WindowHelpers.ForceTopBorder1PixelInsetOnWindows10, unlike the other PowerToys WinUI 3 module windows (AdvancedPaste, EnvironmentVariables, FileLocksmith, Hosts, ImageResizer, Peek, RegistryPreview, Settings). It is a no-op on Windows 11 and fixes the black top border from ExtendsContentIntoTitleBar and wrong window top border color microsoft-ui-xaml#6901 on Windows 10 — the OS this issue was reported against. Happy to drop this hunk if reviewers prefer a minimal diff.

Deliberately not done: wrapping new MainWindow() in try/catch. The failure is a WIL RaiseFailFastException, which managed code cannot intercept; and swallowing managed exceptions there would leave a windowless zombie process still holding the runner's m_hEditorProcess handle, making the runner take its "editor already open" branch and breaking every subsequent launch. That is why #49477 cannot work.

Repo-wide audit

All 15 WinUI 3 executables (UseWinUI=true and OutputType=WinExe) were checked. KeyboardManagerEditorUI was the only one missing the property; the other 14 already set it. Also verified as correct and unchanged: the 7 WinUI class libraries (property is app-level, N/A), runner.vcxproj and PowerRenameUI.vcxproj (native exes, both already true), and PowerToys.MeasureToolCore.vcxproj / FindMyMouse.vcxproj (deliberately false — in-proc module DLLs whose host already establishes the self-contained context).

There is no repo-level default or build guard for this property; it is hand-copied into 17 project files, which is how the hole opened. A Directory.Build.targets guard that errors when an unpackaged Windows App SDK executable omits it would prevent recurrence, but it would catch nothing today, so I left it out of this PR to keep the diff scoped. Happy to open it separately.

Validation Steps Performed

Built KeyboardManagerEditorUI.csproj (x64/Debug) and diffed the build output before and after the change:

before after PowerToys.Hosts.exe (reference)
obj\x64\Debug\Manifests\ (created only by CreateWinRTRegistration) absent present present
activatableClass registrations embedded in the exe 0 1912 1912
assembly references Microsoft.WindowsAppRuntime.Bootstrap.Net / MddBootstrap yes no no

The editor now resolves every Microsoft.UI.* activation app-locally through registration-free WinRT instead of the machine framework package, which removes the mixing hazard.

Not yet validated on Windows 10. I do not have a Windows 10 19045 machine, so the crash repro itself is unverified end-to-end. The deployment-mode change is verified from build output as above; confirmation from the issue reporter would be valuable. A useful discriminator if anyone has the reporter's ProcDump dump: lm v m Microsoft.UI.* — if Microsoft.UI.Input.dll is listed twice from two different paths, the mechanism is confirmed directly.

…nch crash

PowerToys.KeyboardManagerEditorUI.exe fail-fasts with 0xC0000409 during
MainWindow construction. The reported first-chance exception is
ERROR_ALREADY_INITIALIZED (0x800704DF) raised from
Microsoft.UI.Windowing.Core!RegisterWindowFeature, reached through
Window.ExtendsContentIntoTitleBar.

KeyboardManagerEditorUI.csproj was the only WinUI 3 executable in the repo
that did not set WindowsAppSDKSelfContained. With WindowsPackageType=None
and that property absent, the Windows App SDK targets compile in the
MddBootstrap auto-initializer, so the process joins the machine-wide
Microsoft.WindowsAppRuntime framework package to its package graph - while
its own directory, WinUI3Apps, already contains the app-local Windows App
SDK payload shipped by the other 14 self-contained apps. Mixing the two
provenances in one process is what breaks the one-time feature-type
registration. The property was easy to miss because the project imports
Common.SelfContained.props, which sets the unrelated .NET SelfContained
property.

Verified against build output: the exe now embeds 1912 activatableClass
registrations (matching PowerToys.Hosts.exe, previously 0) and the assembly
no longer references Microsoft.WindowsAppRuntime.Bootstrap.Net.

Also fixes two defects specific to this editor, both found while
investigating why the crash left no diagnostics:

- App.xaml.cs initialized the logger via fire-and-forget Task.Run, the only
  one of ~30 Logger.InitializeLogger call sites in the repo to do so. That
  races window creation, and Logger has no buffering or replay, so anything
  logged before the trace listener is attached is lost permanently - which
  is why a crashing launch produced no log file at all. Made it synchronous
  and added a log line before the window is constructed.
- MainWindow did not call WindowHelpers.ForceTopBorder1PixelInsetOnWindows10,
  unlike the other PowerToys WinUI 3 module windows. It is a no-op on
  Windows 11 and fixes the black top border on Windows 10, which is the OS
  this issue was reported against.

Co-Authored-By: Claude <[email protected]>
@moooyo
moooyo marked this pull request as ready for review July 28, 2026 07:04
@moooyo
moooyo enabled auto-merge (squash) July 28, 2026 07:45
@moooyo
moooyo merged commit 130a779 into main Jul 28, 2026
9 checks passed
@moooyo
moooyo deleted the yuleng/keyboardmanager/winui3-editor-selfcontained/1 branch July 28, 2026 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Keyboard Manager] New WinUI3 editor crashes on launch with 0xC0000409 / ERROR_ALREADY_INITIALIZED during title bar initialization

2 participants