Skip to content

fix(windows): resolve 0x800701C0 / 0x80073CF6 install failure by cleaning orphaned AppContainer profiles - #40

Open
dqtx760 wants to merge 2 commits into
freestylefly:mainfrom
dqtx760:fix/windows-appcontainer-cleanup
Open

dqtx760 wants to merge 2 commits into
freestylefly:mainfrom
dqtx760:fix/windows-appcontainer-cleanup

Conversation

@dqtx760

@dqtx760 dqtx760 commented Oct 10, 2026

Copy link
Copy Markdown

解决问题 / Fixes

背景与根因分析 / Root Cause

在 Windows 11(特别是 24H2 / 25H2,Build 26100 及 26200)中,AppXSvc 服务(运行在 NT AUTHORITY\SYSTEM)启用了 PROCESS_MITIGATION_REDIRECTION_TRUST_POLICY(Redirection Trust 缓解策略)。

在以下两种场景下,Add-AppxPackage 会尝试清理旧的 AppContainer 配置文件并调用 DeleteAppContainerProfile:

  1. 覆盖更新时:旧版 Register-ShareTarget.ps1 和 register-dev.ps1 在执行 Add-AppxPackage 前,无差别调用了 Remove-AppxPackage 移除 WeChatBridge.Windows.ShareTarget。Remove-AppxPackage 卸载包后残留了未清理的 AppContainer 用户数据目录 %LOCALAPPDATA%\Packages\<PackageFamilyName>。随后的 Add-AppxPackage 检测到旧状态,触发底层 DeleteAppContainerProfile。
  2. 重装/初次安装失败后重装时(如 [Windows] v1.1.12 安装失败 0x80070643:Add-AppxPackage 无法删除 AppContainer 配置文件 (0x800701C0) #39 反馈的场景):首次安装因权限或环境问题未完成,但在用户目录留下了孤儿 AppContainer 目录或注册表映射。后续安装时,Add-AppxPackage 检测到孤儿 AppContainer 并尝试删除。

当 AppXSvc(SYSTEM 权限)尝试遍历和删除标准用户目录中的 AC 目录时,因其包含 Windows 自动创建的 NTFS Reparse Points / Junctions(例如缓存和临时目录的联接点),NTFS 驱动根据 Redirection Trust 规则拒绝高权限服务穿越低权限创建的联接点,返回 ERROR_UNTRUSTED_MOUNT_POINT (0x1C0,即 0x800701C0),导致 DeleteAppContainerProfile 抛出 IOException,进而导致 Add-AppxPackage 失败(0x80073CF6),整个 MSI 安装以 0x80070643 失败回滚。

修复方案 / Solution

  1. 就地更新不提前卸载:

    • 更新安装时不再对 WeChatBridge.Windows.ShareTarget 调用 Remove-AppxPackage;
    • 仅对历史废弃包名 ChatBridge.Windows.ShareTarget(1.0.7 残留)执行移除;
    • Add-AppxPackage 加上 -ForceApplicationShutdown -ForceUpdateFromAnyVersion,由系统原生进行就地平滑升级,不触发 AppContainer 孤儿删除。
  2. 用户态前置检测并彻底清理孤儿 AppContainer:

    • 新增 Clear-AppContainerProfiles 函数;
    • 若 WeChatBridge.Windows.ShareTarget 未注册(全新安装、重装或上次安装失败残留),在 Add-AppxPackage 前,以当前用户身份主动清理孤儿 AppContainer:
      • 先用 [System.IO.Directory]::Delete($path, $false) 安全解绑解开 Packages 目录中的全部 Junction / Reparse Point,避免触发 0x800701C0;
      • 递归删除残留包目录;
      • 调用 userenv.dll 的 DeleteAppContainerProfile API 彻底清除注册表与 StateRepository 记录;
      • 清理 HKCU 下残留的 AppContainer Mappings 与 Storage 注册表项。
  3. 异常重试容错:

    • Add-AppxPackage 增加 try-catch 兜底,若首次调用失败,自动触发一次完整的 AppContainer 深度清理后再重试一次。
  4. 卸载时清理干净:

    • 在 Unregister-ShareTarget.ps1 中加入 AppContainer 清理逻辑,卸载时彻底移除 profile,避免未来重新安装时留有隐患。
  5. 本地开发脚本同步:

    • 在 windows/scripts/register-dev.ps1 中同步上述更新与清理逻辑。

验证 / Verification

  • 本地构建与自动化测试:全量 295 项测试全部通过(WeChatBridge.Windows.Tests 287 通过,WeChatBridge.Windows.AppTests 8 通过)。
  • Windows 11 Build 26200 实机环境验证:
    • pack-msix.ps1 打包成功;
    • Test-SharePackage.ps1 数据格式与资产契约校验全部通过;
    • register-dev.ps1 首次注册成功;
    • WeChatBridge.ShareTarget.exe --registration-check 验证包身份与 AUMID 获取完全正常;
    • register-dev.ps1 多次重复更新安装无报错;
    • Unregister-ShareTarget.ps1 卸载及 profile 清理测试正常;
    • 卸载后重新注册测试无 0x800701C0 报错,注册顺畅通过。

…ppContainer profiles

- Fixes freestylefly#39 and freestylefly#38
- Windows 11 (24H2/25H2, Build 26100/26200) enables PROCESS_MITIGATION_REDIRECTION_TRUST_POLICY
  on AppXSvc (SYSTEM), which blocks traversing or deleting user-created filesystem junctions
  inside %LOCALAPPDATA%\Packages\<PackageFamilyName>, returning ERROR_UNTRUSTED_MOUNT_POINT
  (0x800701C0) when DeleteAppContainerProfile is called.
- In-place updates no longer needlessly call Remove-AppxPackage before Add-AppxPackage,
  avoiding leaving residual unlinked AppContainer state and instead using
  -ForceApplicationShutdown -ForceUpdateFromAnyVersion directly.
- Clear orphaned AppContainer profiles, junctions, and directories via Userenv
  DeleteAppContainerProfile and safe directory unbinding before registering if the package
  is not currently registered.
- Add retry mechanism to Add-AppxPackage that purges orphaned profiles and retries upon failure.
- Ensure Unregister-ShareTarget.ps1 purges AppContainer profiles on uninstallation.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant