microsoft / microsoft/winget-cli

WinGet fails with 0x80070005 (Access Denied) on install after uninstallation is prompted when the package installer type changes (Win32 to MSIX). This can result in a corrupted system

Open
#6,488 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Issue-Bug Possible-Duplicate
Dominant language
C++
Stars
26.4k
Forks
1.8k
Avg merge
1d 11h
Merged PRs (30d)
15

Description

Relevant area(s)

WinGet CLI

Relevant command(s)

No response

Brief description of your issue
Duplication / Disambiguation
  • Mostly tracked under #2883
  • That does not cover the potential for the system to end up in an unrecoverable state
Description

When a third-party application package repository shifts its primary deployment manifest architecture mid-lifecycle (specifically from a traditional Win32 .exe/.msi to a modern virtualized .msix container), the Windows Package Manager fails to resolve the transition state when using --scope machine.

Even when executing within an elevated administrative terminal (Run as Administrator), WinGet downloads, verifies, and stages the deployment to 92%, before crashing with Installer failed with exit code: 0x80070005 : Access is denied.

This happens because the background AppX Deployment Service (AppXSvc via COM loopback interfaces) detects a structural system namespace collision between the legacy Win32 execution footprints/registry keys and the incoming MSIX provision request (ProvisionPackageOperation). WinGet cannot automatically reconcile this cross-context upgrade boundary.

Related Issue Trackers

This bug intersects with several verified tracking items on the Microsoft WinGet repository regarding cross-technology upgrades and installer scope mismatch logic:

  • #3817 : Tracks why the winget upgrade --all script pipeline silently skips packages or flags warnings when an underlying installer technology transitions mid-lifecycle.
  • #2826 : Details the tracking thread where manual package overrides encounter installer technology mismatches or return structured permission blocks.
  • #4677 : Focuses on the current architectural limitations of flags like --uninstall-previous when attempting to purge legacy Win32 executable footprints prior to staging an MSIX container package.
Steps to reproduce
  1. Have an older version of Slack installed system-wide via WinGet (historically distributed as a Win32 standalone payload). All of the following are in an elevated terminal for --scope machine operations.

  2. Execute a global upgrade sweep: winget upgrade --all.

  3. WinGet includes Slack in the list of packages to install, but then silently skips it. The numerical difference between the two is summarised.

  4. Slack could be discovered by manual reconciliation, or by following up with any of:

    • winget list --upgrade-available --include-unknown followed by winget upgrade --id SlackTechnologies.Slack --exact --include-unknown
    • winget upgrade --all --include-unknown
  5. That will fail, indicating "A newer version was found, but the install technology is different from the current version installed. Please uninstall the package and install the newer version."

  6. Uninstall the asset to allow a fresh installation: winget uninstall --all-versions --id SlackTechnologies.Slack --exact

  7. Attempt a clean machine-scoped deployment:

    winget install --id SlackTechnologies.Slack --exact --source winget --scope machine

  8. Result: The process fails at exactly 92% staging completion with error 0x80070005. That is repeatable between cleanup attempts.

  9. Note: Despite numerous cleanup strategies, I have been unable to reinstall Slack in --scope machine.

Context
PS C:\Users\simon\AppData\Local\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\DiagOutputDir> Get-ChildItem *.log | Select-String -Pattern 'slack' -List | ForEach-Object { Select-String -Path $_.Path -Pattern 'Reading cached file.*manifests' }

WinGet-2026-08-23-13-09-18.472.log:1101:2026-08-23 13:09:19.613 <V> [CORE] Reading cached file [C:\Users\simon\AppData\
Local\Temp\WinGet\cache\V2_M\Microsoft.Winget.Source_8wekyb3d8bbwe\manifests/s/SlackTechnologies/Slack/4.51.191/4b4a]
WinGet-2026-08-23-16-45-10.476.log:533:2026-08-23 16:45:11.300 <V> [CORE] Reading cached file [C:\Users\simon\AppData\L
ocal\Temp\WinGet\cache\V2_M\Microsoft.Winget.Source_8wekyb3d8bbwe\manifests/s/SlackTechnologies/Slack/4.51.191/4b4a]
WinGet-2026-08-23-16-46-05.341.log:1101:2026-08-23 16:46:06.505 <V> [CORE] Reading cached file [C:\Users\simon\AppData\
Local\Temp\WinGet\cache\V2_M\Microsoft.Winget.Source_8wekyb3d8bbwe\manifests/s/SlackTechnologies/Slack/4.51.191/4b4a]


PS C:\Users\simon\AppData\Local\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\DiagOutputDir>
Other candidates for experimentation
  • winget upgrade --id Pingman.PingPlotter --exact --include-unknown
Expected behavior
Technical Conclusion & Desired Feature Request

The 0x80070005 error is triggered because WinGet's packaging framework lack the capability to seamlessly step down, decouple, or cleanly scrub system component references when a package tracking target transitions from a legacy Win32 executable registry mapping to an active AppX provision model.

Proposed Resolution Steps for WinGet:
  • Introduce automated validation hooks to handle the "install technology is different" warning smoothly.
  • Implement a native --uninstall-previous-native switch capable of calling deep cleanup procedures to release active App Execution Aliases and clear background registry namespaces before initiating a machine-scoped ProvisionPackage operation.
Actual behavior
Detailed Logs & Diagnostics

When capturing the failure via --verbose-logs, the breakdown occurs precisely at the handoff transition from file verification to the Windows provision environment loopback:

2026-08-23 16:46:06.507 <V> [CLI ] Starting installer selection.
2026-08-23 16:46:12.125 <I> [CORE] Successfully completed #0
2026-08-23 16:46:12.125 <I> [CORE] Starting ProvisionPackage operation #1: com.tinyspeck.slackdesktop_8yrtsj140pw4g
2026-08-23 16:46:12.141 <I> [CORE] Begin waiting for operation #1
2026-08-23 16:46:12.141 <I> [CORE] Begin blocking for operation #1
2026-08-23 16:46:12.252 <E> [CORE] Deployment operation #1: Deployment ProvisionPackageOperation operation with target volume C: on Package com.tinyspeck.slackdesktop_4.51.191.0_x64__8yrtsj140pw4g from:   failed with error 0x80070005. See http://microsoft.com for help diagnosing app deployment issues.
2026-08-23 16:46:12.252 <E> [FAIL] C:\__w\1\s\external\pkg\src\AppInstallerCommonCore\Deployment.cpp(54)\WindowsPackageManager.dll!00007FFF086E6EE2: (caller: 00007FFF086E2F15) Exception(1) tid(5158) 80070005 Access is denied.
    Msg:[Operation failed: Deployment ProvisionPackageOperation operation with target volume C: on Package com.tinyspeck.slackdesktop_4.51.191.0_x64__8yrtsj140pw4g from:   failed with error 0x80070005. See http://microsoft.com for help diagnosing app deployment issues.] 
2026-08-23 16:46:12.412 <E> [CLI ] MSIX installer failed: 2147942405
2026-08-23 16:46:12.412 <E> [CLI ] Terminating context: 0x80070005 at C:\__w\1\s\external\pkg\src\AppInstallerCLICore\Workflows\InstallFlow.cpp:239
Manifest Architecture Shift Proof

An analysis of the raw cached manifest highlights why forcing specific scope switches fails. The available installer nodes bind properties exclusively across misaligned paradigms:

Installers:
- Architecture: x64
  InstallerType: exe
  InstallerUrl: https://downloads.slack-edge.com/...
  ProductCode: slack
  Scope: user  # <--- Win32 EXE hardcoded strictly to Single User Context
- Architecture: x64
  InstallerType: msix  # <--- Modern MSIX container chosen dynamically for Machine Scope
  InstallerUrl: https://downloads.slack-edge.com/...
  PackageFamilyName: com.tinyspeck.slackdesktop_8yrtsj140pw4g
Deep Diagnostics and Bypasses Tested
  1. Sysinternals Process Monitor (ProcMon) Isolation: Direct filtering for ACCESS DENIED on file system/registry transactions yields 0 results from winget.exe. This establishes that the access denial does not stem from local file read/write permissions issues. Instead, it is an explicit structural COM error value returned to WinGet by Windows' AppX servicing subsystem.
  2. System Environment Cleaning (Failed to fix WinGet): Executing deep cleanup tasks via DISM.exe /Online /Cleanup-Image /StartComponentCleanup /ResetBase, clearing the local App Execution Alias pathing hooks ($env:LOCALAPPDATA\Microsoft\WindowsApps), and deleting old registry Uninstall keys fails to unblock WinGet.
  3. The Native PowerShell DISM Bypass (Succeeded): Bypassing the WinGet deployment wrapper entirely and processing the target raw manifest package link directly via native deployment commands succeeds cleanly:
Invoke-WebRequest -Uri "https://downloads.slack-edge.com/..." -OutFile "$env:TEMP\Slack.msix"
Add-AppxProvisionedPackage -Online -PackagePath "$env:TEMP\Slack.msix" -SkipLicense

Note: Once injected via DISM, winget list tracks the metadata appropriately. However, a subsequent winget uninstall strips only the active user layer, leaving WinGet's backend tracking index permanently stuck in a loop.

Environment
- Package Manifest Id: SlackTechnologies.Slack


PS C:\Users\simon> winget --info
Windows Package Manager v1.29.290
© 2026 Microsoft. All rights reserved.

Windows: Windows.Desktop v10.0.26100.9168
System Architecture: X64
Package: Microsoft.DesktopAppInstaller v1.29.290.0

WinGet Directories
-----------------------------------------------------------------------------------------------------------------------
Logs                               %LOCALAPPDATA%\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\Diag…
User Settings                      %LOCALAPPDATA%\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\sett…
Portable Links Directory (User)    %LOCALAPPDATA%\Microsoft\WinGet\Links
Portable Links Directory (Machine) C:\Program Files\WinGet\Links
Portable Package Root (User)       %LOCALAPPDATA%\Microsoft\WinGet\Packages
Portable Package Root              C:\Program Files\WinGet\Packages
Portable Package Root (x86)        C:\Program Files (x86)\WinGet\Packages
Installer Downloads                %USERPROFILE%\Downloads
Configuration Modules              %LOCALAPPDATA%\Microsoft\WinGet\Configuration\Modules

Links
---------------------------------------------------------------------------
Privacy Statement   https://aka.ms/winget-privacy
License Agreement   https://aka.ms/winget-license
Third Party Notices https://aka.ms/winget-3rdPartyNotice
Homepage            https://aka.ms/winget
Windows Store Terms https://www.microsoft.com/en-us/storedocs/terms-of-sale

Admin Setting                             State
--------------------------------------------------
LocalManifestFiles                        Disabled
BypassCertificatePinningForMicrosoftStore Disabled
InstallerHashOverride                     Enabled
LocalArchiveMalwareScanOverride           Disabled
ProxyCommandLineOptions                   Disabled
ConfigurationProcessorPath                Disabled
DefaultProxy                              Disabled
PS C:\Users\simon>

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the Slack transition with the listed winget commands and capture verbose logs. Trace the reported failure through external/pkg/src/AppInstallerCommonCore/Deployment.cpp:54 and AppInstallerCLICore/Workflows/InstallFlow.cpp:239, comparing the Win32 and MSIX paths. Done means the transition no longer leaves the machine or WinGet tracking state unrecoverable after the 0x80070005 failure.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, powershell
Domain
cli, operating-systems
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.