#52888: fix: don't let pending shell operations block app exit on Windows
Merged
Created: Aug 17, 2026, 12:20:07 AM
Merged: Aug 17, 2026, 3:11:50 AM
5 comments
Target: main
Description of Change
Fixes #52141 (the crash cases > "promise-destroy-crash" flake on Windows), which turned out to be a real quit hang rather than a test problem.
shell.openExternal()/shell.openPath()/shell.showItemInFolder()post theirShellExecuteEx()work to a COM STA thread-pool task with the defaultSKIP_ON_SHUTDOWNbehaviour. ASKIP_ON_SHUTDOWNtask that has already started blocksThreadPoolInstance::Shutdown(), andShellExecuteEx()can block inside the OS for as long as Windows is showing UI for the request — e.g. the "you'll need a new app to open this link" dialog for a scheme with no registered handler (its helper thread sits in a synchronous cross-process COM release intoOpenWith.exeuntil the dialog is dismissed). Net effect:app.quit()fireswill-quit/quit, then the browser main thread parks inTaskTracker::CompleteShutdown()and the process never exits until the user clicks OK.- Post these tasks with
CONTINUE_ON_SHUTDOWNinstead. This matches Chrome'splatform_util::OpenItem, which uses that trait for exactly this reason ("can hang shutdown without this trait as it may result in an interactive dialog"). The tasks only touch their bound arguments and OS APIs, so letting shutdown proceed while one is still blocked in the shell is safe.
Verified on Windows CI by looping the promise-destroy-crash fixture with native stack capture on hang: current behaviour hung 132/243 runs (main thread in TaskTracker::CompleteShutdown, worker in ShellExecuteExW → CShellExecute::_RunThreadMaybeWait, shell helper thread in combase!RemoteReleaseRifRef); with this change 0/243.
Checklist
- PR description included and stakeholders cc'd
-
npm testpasses - PR release notes describe the change in a way relevant to app developers, and are capitalized, punctuated, and past tense.
Release Notes
Notes: Fixed an issue on Windows where the app process could fail to exit after app.quit() while a shell.openExternal() or shell.openPath() call was still waiting on a system "Open with" dialog.
Backports
44-x-y
MergedPR Number
#52898Merged At
Aug 17, 2026, 4:57:35 AM
Released In
v44.0.0-beta.5Release Date
Aug 17, 2026, 3:01:12 PM
Semver Impact
Major
Breaking changes
Minor
New features
Patch
Bug fixes
None
Docs, tests, etc.
Semantic Versioning helps users understand the impact of updates:
- Major (X.y.z): Breaking changes that may require code modifications
- Minor (x.Y.z): New features that maintain backward compatibility
- Patch (x.y.Z): Bug fixes that don't change the API
- None: Changes that don't affect using facing parts of Electron