原因分析、解决方案
# 原因分析
前置条件 1:之前偷懒用 Microsoft Store 安装 python 时,遇到了奇怪的权限问题(通过微软商店安装的 app 文件夹会有特殊权限限制,实测可以删除文件,但无法新建 / 重命名文件),测试的时候不小心修改了
Program Files\WindowsApps
文件夹的权限面板
前置条件 2:通过 Win+X 菜单和 Win+R 运行 wt.exe 都无法运行(打开后进程自动退出,且无 UI 提示),但是可以通过开始菜单和其他 terminal 中输入 wt.exe 运行
可以通过 terminal 中输入 wt.exe 运行就说明并非是应用损坏,而是启动方式问题,直觉想到可能是 Win+X 菜单和 Win+R 附带了什么奇怪的参数,想到火绒剑记录系统日志分析,日志记录如下:
发现两个 wt.exe 的路径竟然不一样,位于 \AppData\Local\Microsoft\WindowsApps\
的 wt.exe 似乎是一个软链接,神奇的是资源管理器中显示这个文件是一个 0byte 的 exe,而不是.lnk,不知道为什么…
总之,最终实际运行的还是位于 \WindowsApps\Microsoft.WindowsTerminal_1.12.10983.0_x64__8wekyb3d8bbwe\
下那个实际的 wt.exe(见下图),而且实测直接打开实际的 wt.exe 效果同 Win+R 打开(无反应),而打开软链接的 wt.exe 就可以正常运行
那么现在有两个问题:
- 同一个 wt.exe 命令,为什么 Win+R(Win+X 菜单实际上执行的也是 Win+R)和 terminal 找到并调用的文件位置不同?
- 为什么软链接的 wt.exe 就能正常运行,而实际的 wt.exe 却无法运行,明明本质上都是同一个文件?
关于问题 1:我的猜想是系统环境变量 Path 中对于这两个路径的定义, \WindowsApps\Microsoft.WindowsTerminal_1.12.10983.0_x64__8wekyb3d8bbwe\
位于 \AppData\Local\Microsoft\WindowsApps\
之前,所以优先调用了实际的 wt.exe,然而事实上 Path 中根本就只定义了 \AppData\Local\Microsoft\WindowsApps\
,所以 Win+R 调用程序的逻辑应该与 terminal 不同,可能不依靠 Path 或 Path 的权重在较后位置(这也就对应了解决方法 1)
关于问题 2:我的猜想是所处位置权限不同或调用方不同,导致实际运行 wt.exe 时,wt.exe 内部调用 syscall 被 Permission Denied(不知道算不算是 bug?),由于之前改过 WindowsApps
文件夹权限,直觉想到应该是 WindowsApps
有特殊权限系统导致,Google 后发现有很多由 WindowsApps
权限修改导致的 UWP 应用故障案例(这也就对应了解决方法 2)
# 解决方案
由上面的分析,想到下面的解决方法:
- 修改 Win+R 调用逻辑
- 重置
WindowsApps
权限
这两个方案在国内论坛上都基本找不到相关资料,好在 Github 和 StackOverflow 上有遇到同样问题的老哥
关于方案 1:需要修改注册表中的值: HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\wt.exe
下从 C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.12.10983.0_x64__8wekyb3d8bbwe\
路径到 C:\Users\用户名\AppData\Local\Microsoft\WindowsApps\
,实测可行,如下图:
关于方案 2:可以尝试使用 icacls "C:\Program Files\WindowsApps" /reset /t /c /q
命令重置权限(需要 SYSTEM 权限才能运行该命令,可以借助 PsExec, psexec.exe -s icacls "C:\Program Files\WindowsApps" /reset /t /c /q
),不过请注意:这个 reset 命令似乎需要先前有过备份,不然特殊权限很难恢复,实测在我的电脑上无效。替代方案:Github 老哥写的 powershell 脚本(没尝试过,可用性未知)
参考:
Github Issue 7081
Github Issue 7974
如何将 WindowsApps 文件夹权限重置为默认值
重置 C:\Program Files\WindowsApps 的默认 ACL