[Keyboard Manager] Build the WinUI 3 editor self-contained to fix launch crash (0xC0000409) - #49524
Merged
moooyo merged 1 commit intoJul 28, 2026
Conversation
…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
marked this pull request as ready for review
July 28, 2026 07:04
shuaiyuanxx
approved these changes
Jul 28, 2026
moooyo
enabled auto-merge (squash)
July 28, 2026 07:45
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary of the Pull Request
PowerToys.KeyboardManagerEditorUI.exefail-fasts with0xC0000409(STATUS_STACK_BUFFER_OVERRUN) duringMainWindowconstruction, so the new Keyboard Manager editor never opens.KeyboardManagerEditorUI.csprojwas 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::ApiExceptioncarrying0x800704DF(ERROR_ALREADY_INITIALIZED):ExtendsContentIntoTitleBaris the site, not the cause — it is simply the first user statement that crosses XAML -> Windowing -> Input.microsoft.windowsappsdk.foundation/*/buildTransitive/Microsoft.WindowsAppSDK.BootstrapCommon.targetsturns the bootstrapper on precisely when this project's shape is hit:That compiles in
MddBootstrapAutoInitializer.cs, which joins the machine-wideMicrosoft.WindowsAppRuntimeMSIX framework package to the process package graph beforeMain. 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 inMicrosoft.UI.Inputcollides.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\PowerToyschange nothing. The classic C++ editor is unaffected because it uses WinUI 2 XAML Islands and ships no Windows App SDK at all.PowerToys.Settings.exeran healthily in the same elevated session on the same day while doing strictly more title-bar work (it setsExtendsContentIntoTitleBartwice and drivesInputNonClientPointerSource.GetForWindowIdon everySizeChanged) — because it is self-contained.Two additional defects fixed
Both were found while investigating why the crash left no diagnostics at all:
App.xaml.csinitialized the logger via fire-and-forgetTask.Run— the only one of ~30Logger.InitializeLoggercall sites in the repo to do so. That races window creation, andLoggerhas no buffering or replay (Trace.WriteLinestraight through, listener attached inInitializeLogger), so anything logged before the listener is attached is lost permanently. This is why the user's bug report bundle contains aWinUI3Editorlog for the day it worked and no log file at all for the day it crashed. Made synchronous, ordered to matchFileLocksmithXAML/App.xaml.cs, plus a log line before the window is constructed.MainWindownever calledWindowHelpers.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()intry/catch. The failure is a WILRaiseFailFastException, which managed code cannot intercept; and swallowing managed exceptions there would leave a windowless zombie process still holding the runner'sm_hEditorProcesshandle, 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=trueandOutputType=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.vcxprojandPowerRenameUI.vcxproj(native exes, both alreadytrue), andPowerToys.MeasureToolCore.vcxproj/FindMyMouse.vcxproj(deliberatelyfalse— 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.targetsguard 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:PowerToys.Hosts.exe(reference)obj\x64\Debug\Manifests\(created only byCreateWinRTRegistration)activatableClassregistrations embedded in the exeMicrosoft.WindowsAppRuntime.Bootstrap.Net/MddBootstrapThe 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.*— ifMicrosoft.UI.Input.dllis listed twice from two different paths, the mechanism is confirmed directly.