microsoft / microsoft/PowerToys
[Installer] Partial WinUI3Apps copy failures can leave a mixed-version installation after upgrade
@moooyo is already working on this.
Since Aug 18, 2026.
- Dominant language
- C
- Stars
- 139k
- Forks
- 8.6k
- PR merge metrics
- PR metrics pending
Description
Current status and related PR
This issue remains open for preventing mixed-version WinUI3Apps dependencies when files cannot be replaced during upgrade.
Related PR #49996, currently a draft at f7106d30ea, replaces the manifest-driven copy/delete custom actions with MSI DuplicateFile authoring while preserving payload deduplication. Its local build and MSI artifact comparison passed for both installation scopes, including 435 matching duplicate mappings. Its scope is normal file ownership and custom-action cleanup; it does not implement files-in-use preflight, reliable reboot replacement, or installed-content verification.
The original inconsistent installation is confirmed. The exact cause of its failed copy operations is not known because the upgrade MSI log is unavailable. Review also reproduced locked-destination limitations in controlled minimal MSIs; those results and the remaining acceptance criteria are below. Neither this investigation nor #49996 establishes that the mixed-version dependencies were the sole cause of the crashes in #49850.
Microsoft PowerToys version
0.101.2241.0
Installation method
GitHub, machine-wide installer
Area(s) with issue?
Installer
Steps to reproduce / observed upgrade path
This issue was identified while investigating #49850 and its PowerToys bug report.
The report shows this upgrade path and resulting state; it does not provide a deterministic reproduction of the original copy failure:
- The affected machine previously had PowerToys 0.101.2211.0 installed machine-wide.
- Upgrade to 0.101.2241.0; the upgrade reports success.
- Compare shared dependencies under the installation root and
WinUI3Apps: some destination copies remain from the previous version. - Image Resizer, Settings, and Peek fail during WinUI/MRT initialization.
Files held open or otherwise not replaceable are a scenario that must be handled, but the exact failing operation and locking process on the reported machine cannot be identified without its 0.101.2241.0 MSI log. The incomplete installation was cross-checked against the official release MSI.
✔️ Expected Behavior
Every required shared dependency materialized under WinUI3Apps must match the intended new payload. In the affected release, this set is defined by WinUI3Apps\hardlinks.txt; in #49996 it is authored in the MSI DuplicateFile table.
- Successful installation with exit code
0must leave the complete expected set consistent immediately. - If completion is deferred to a reboot, replacement must actually be scheduled and the complete set must be consistent before PowerToys can run after reboot. Exit code
3010alone is not sufficient evidence. - If required files cannot be replaced or reliably scheduled, fail safely without leaving a partially upgraded or unusable installation. Prefer detecting unresolved locks before removing the old product.
❌ Actual Behavior in the reported release
CreateWinAppSDKHardlinksCA tolerates individual copy failures and fails the installation only when every copy fails. A partially failed pass can therefore report success while retaining old destination files.
The affected installation contained 0.101.2241.0 applications and PRIs, but several shared dependencies in WinUI3Apps were still from 0.101.2211.0:
| File | Installation root | WinUI3Apps |
|---|---|---|
PowerToys.Common.UI.dll |
0.101.2241.0 | 0.101.2211.0 |
PowerToys.FancyZonesEditorCommon.dll |
0.101.2241.0 | 0.101.2211.0 |
PowerToys.Interop.dll |
0.101.2241.0 | 0.101.2211.0 |
PowerToys.ManagedCommon.dll |
0.101.2241.0 | 0.101.2211.0 |
PowerToys.ManagedTelemetry.dll |
0.101.2241.0 | 0.101.2211.0 |
PowerToys.WorkspacesCsharpLibrary.dll |
0.101.2241.0 | 0.101.2211.0 |
Microsoft.Windows.ApplicationModel.Resources.dll also had different reported hashes:
- Installation root:
01e4784a6491e2a325853151b77310c8 WinUI3Apps:629c9305c670bb4489aa100849c59375
The Image Resizer, Settings, and Peek executable/DLL/PRI sets were already 0.101.2241.0. Their failures shared this signature:
Microsoft.UI.Xaml.dll3.2.2.0- exception
0xc000027b - inner WER HRESULT
0x80070002(ERROR_FILE_NOT_FOUND)
This is evidence of crashes alongside a mixed-version installation, not proof that the dependency mismatch explains every reported crash.
Upload Bug Report ZIP-file
PowerToysReport_2026-08-12-20-11-09.zip
Additional investigation
Cross-check against the official 0.101.2241.0 machine-wide MSI:
- The affected installation root hashes match the official MSI payload.
- The MSI packages these shared files at the root and lists their destination copies in
WinUI3Apps\hardlinks.txt; it does not package those copies directly underWinUI3Apps. - The report and MSI contain the same manifest (MD5
00501cbbccf146a4319ef2df6810877e), including every stale file listed above. - The stale destinations therefore reflect incomplete installation-time copying/synchronization, rather than a release payload already containing those mismatched copies.
The affected custom action uses fs::copy_file(..., overwrite_existing, ec) but returns installation failure only for created == 0 && failed > 0. PR #49996 removes that custom-action path. Removing it does not by itself establish safe behavior for every locked-file case.
Locked-file results from PR review
Local review on 2026-08-28 used controlled per-user, two-version minimal MSIs: the old version had externally materialized destination copies, and the new version used registry-keypath source components with nested CopyFile, matching the relevant PowerToys authoring and early major-upgrade sequence. A separate process held one destination open throughout the upgrade; another destination remained writable.
| Locked destination | Observed result |
|---|---|
| Versioned PE DLL, 1.0.0.0 → 2.0.0.0 | Error 1310 / Windows error 32; upgrade returned 1603, with no pending replacement. The early major upgrade had already removed the old product, and rollback removed the new root payload. |
| Unversioned file | Upgrade returned 3010 and set ReplacedInUseFiles=1, but the root contained new content while the destination stayed old. No replacement for the test file was found in PendingFileRenameOperations or other inspected persistent recovery state. After a real Windows reboot, the destination was still old and the new MSI remained registered as installed. |
These are minimal-MSI reproductions, not full PowerToys upgrade acceptance. They demonstrate that standard DuplicateFile authoring alone is insufficient to claim this issue resolved. The PR's successful build, payload/hash comparisons, and MSI-table verifier do not exercise these runtime conditions.
Remaining work and acceptance criteria
- Release known locks before upgrade, using Restart Manager and/or the existing process-termination mechanism as appropriate.
- If locks remain, detect them before
RemoveExistingProductsand preserve the existing installation. Any alternative failure path must demonstrate complete recovery. - Verify the installed duplicate set against the intended new payload, including source files that may themselves still be pending replacement. Root/destination equality alone is insufficient if both retain old content.
- If reboot replacement is supported, validate actual scheduling and post-reboot content before allowing PowerToys to run; do not infer completion from
3010orReplacedInUseFilesalone. - Log replacement failures with source, destination, Windows error, and locking process when available.
- Add real PowerToys upgrade acceptance for root-only, destination-only, both-side, and multiple locks, covering versioned and unversioned files and both per-machine/per-user scopes. Require immediate full consistency, verified completion after reboot, or safe failure preserving the old installation.
Related original implementation: #47233. Related cleanup PR: #49996. Original application report: #49850.
OS: Windows 11 25H2, build 26200.
Install scope: per-machine.
PowerToys was not running elevated.
Other Software
The previous 0.101.2211.0 deployment was distributed through a corporate software repository. The exact file-locking process is unknown because the failing 0.101.2241.0 MSI log is unavailable.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.