Fix abandoned COM activation lifetime - #549
Conversation
Give exact -Embedding startup a five-second handoff lease without coupling Terminal lifetime to COM object counts. A real or restored window cancels the lease, AllowHeadless remains authoritative, and reentrant window creation is protected from queued timer expiry. Add packaged lifecycle coverage for abandoned activation, valid handoff, and explicit headless mode. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dd185e71-68e2-4772-83fe-525e877c54f4
There was a problem hiding this comment.
Pull request overview
This PR fixes a WindowsTerminal COM local-server activation edge case where a -Embedding-launched process could linger indefinitely (blocking MSIX upgrades), by adding a bounded startup “handoff lease” that exits if no real window is created—while preserving existing “final window closed” behavior and respecting AllowHeadless.
Changes:
- Added a 5-second
-Embeddingstartup timer inWindowEmperorand ensured it’s safely canceled/neutralized during window creation (including message-pump/reentrancy races). - Added packaged E2E coverage for abandoned activation exit, valid handoff survival, and explicit headless survival.
- Updated E2E suite documentation and release checklist mappings for the new coverage items (C246–C248).
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
src/cascadia/WindowsTerminal/WindowEmperor.h |
Adds handoff timer ID constant and a counter to guard against reentrant window-creation races. |
src/cascadia/WindowsTerminal/WindowEmperor.cpp |
Implements the 5s -Embedding handoff lease, cancels it on window creation, and handles the timer message safely. |
test/e2e/tests/Feature.Packaging.Tests.ps1 |
Adds 3 E2E tests validating the COM activation lifetime behavior (abandoned, valid handoff, AllowHeadless). |
test/e2e/ItE2E/Private/Paths.ps1 |
Adds helper to read the protocol COM CLSID from the installed package manifest. |
test/e2e/ItE2E/ItE2E.psm1 |
Exports the new Get-ItProtocolComClsid helper for test use. |
test/e2e/README.md |
Updates suite description and case count to reflect new COM activation lifecycle tests. |
doc/release-check-list.md |
Adds new checklist items C246–C248 mapped to the new E2E coverage. |
| // | ||
| // TODO: Here we could start a timer and exit after, say, 5 seconds | ||
| // if no windows are created. But that's a minor concern. | ||
| // DCOM may activate us for a ConPTY handoff that never arrives. |
check-spelling-bot Report
|
| Dictionary | Entries | Covers | Uniquely |
|---|---|---|---|
| cspell:csharp/csharp.txt | 32 | 2 | 2 |
| cspell:aws/aws.txt | 232 | 2 | 2 |
| cspell:fonts/fonts.txt | 536 | 1 | 1 |
Consider adding to the extra_dictionaries array (in the .github/actions/spelling/config.json file):
"cspell:csharp/csharp.txt",
"cspell:aws/aws.txt",
"cspell:fonts/fonts.txt",
To stop checking additional dictionaries, put (in the .github/actions/spelling/config.json file):
"check_extra_dictionaries": []Pattern suggestions ✂️ (1)
You could add these patterns to .github/actions/spelling/patterns/55cd53b0bcb5da6ba5fa83c5d891ebab76c5d45d.txt:
# Automatically suggested patterns
# hit-count: 1 file-count: 1
# container images
image: [-\w./:@]+
Alternatively, if a pattern suggestion doesn't make sense for this project, add a # to the beginning of the line in the candidates file with the pattern to stop suggesting it.
Warnings and Notices ⚠️ (2)
See the 📂 files view, the 📜action log, 👼 SARIF report, or 📝 job summary for details.
| Count | |
|---|---|
| ℹ️ candidate-pattern | 1 |
| 53 |
See
✏️ Contributor please read this
By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.
If the listed items are:
- ... misspelled, then please correct them instead of using the command.
- ... names, please add them to
.github/actions/spelling/allow/names.txt. - ... APIs, you can add them to a file in
.github/actions/spelling/allow/. - ... just things you're using, please add them to an appropriate file in
.github/actions/spelling/expect/. - ... tokens you only need in one place and shouldn't generally be used, you can add an item in an appropriate file in
.github/actions/spelling/patterns/.
See the README.md in each directory for more information.
🔬 You can test your commits without appending to a PR by creating a new branch with that extra change and pushing it to your fork. The check-spelling action will run in response to your push -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. 😉
If the flagged items are 🤯 false positives
If items relate to a ...
-
binary file (or some other file you wouldn't want to check at all).
Please add a file path to the
excludes.txtfile matching the containing file.File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.
^refers to the file's path from the root of the repository, so^README\.md$would exclude README.md (on whichever branch you're using). -
well-formed pattern.
If you can write a pattern that would match it,
try adding it to thepatterns.txtfile.Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.
Note that patterns can't match multiline strings.
Summary
-Embeddingstartup a bounded five-second window-handoff leaseWM_TIMERracesAllowHeadlessbehavior without coupling lifetime to COM object countsThis replaces #22 with a fix aligned to the current classic COM architecture. Orphaned
wtcli listenclient cleanup remains a separate focused follow-up because subscriptions intentionally do not own Terminal process lifetime.Validation
cmd.exe /c "tools\razzle.cmd && cd src\cascadia\WindowsTerminal && bx"CascadiaPackagebuild and deploymentFeature.Packaging.Tests.ps1against the deployed Dev package: 17 passed, 0 failed, 5 expectedwinapp-dependent skips