WinGet说大成功
开窗一看了无踪
八零零七零零五
高呼给我转人工
以上是定场诗。
Winget 说安装成功,但 Oh My Posh 根本没装上:一次 MSIX 0x80070005 排障记录
以上是副标题
缘起:办公用机最近要下载运行我之前托管在gitlab上的ps1脚本,可是平时我用的是WSL,于是我用winget给Windows装个git,然后就开始大折腾。
C 我的私钥在WSL里呢
# 看看WSL的发行版叫什么名字
wsl --list
# 复制私钥
Copy-Item "\\wsl.localhost\Ubuntu-26.04\home\<wslusername>\.ssh\id_ed25519" -Destination "$HOME\.ssh\id_ed25519" -Force
# 只允许当前用户读写
icacls "$HOME\.ssh\id_ed25519" /inheritance:r
icacls "$HOME\.ssh\id_ed25519" /grant:r "${env:USERNAME}:(R,W)"
# 可选:这个可以不用输入passphrase,将私钥安全托管到后台代理,
Start-Service ssh-agent
ssh-add "$HOME\.ssh\id_ed25519"
ssh-add -l
ssh -T [email protected]
Dm Windows 11自带的Powershell弱爆了
Windows 11 自带的 PowerShell 版本太老,很多现代模块都无法正常使用。我装个最新的 PowerShell 7,又叫pwsh。
去微软官方 GitHub 仓库下载了最新稳定版 PowerShell-7.6.6-win-x64.msi 一路 “Next” 到底,彻底重启 Windows Terminal。
初始化 PowerShell Profile
在 PowerShell 7 中安装 posh-git 模块,并通过 Winget 安装 Oh My Posh:
Install-Module posh-git -Scope CurrentUser -Force -AllowClobber
winget install JanDeDobbeleer.OhMyPosh --source winget
编辑当前用户的 PowerShell Profile:
notepad $PROFILE
写入以下内容:
# 引入 Git 状态和补全
Import-Module posh-git
# 初始化 Oh My Posh
oh-my-posh init pwsh --config "jandedobbeleer" | Invoke-Expression
Winget 看起来也非常配合:
Found Oh My Posh [JanDeDobbeleer.OhMyPosh] Version 31.3.0
Successfully verified installer hash
Starting package install...
Successfully installed
运行 . $PROFILE ,说没有Oh My Posh!
关上Windows Terminal再开,还是没有!
很好,下一步测试:
oh-my-posh version
结果:
oh-my-posh: The term 'oh-my-posh' is not recognized...
Em 故事就从这里开始了
PATH在哪?
这是最常见的情况。
关闭 PowerShell,重新打开,再试:
Get-Command oh-my-posh -ErrorAction SilentlyContinue
where.exe oh-my-posh
全部为空。
再检查 Winget:
winget list --id JanDeDobbeleer.OhMyPosh
结果更加奇怪:
No installed package found matching input criteria.
也就是说:
- Winget 刚刚告诉我
Successfully installed - PATH 里没有
oh-my-posh - Winget 自己也认为 Oh My Posh 没安装
这就不是简单的 PATH 刷新问题了。
开启 Winget verbose log
重新安装:
winget install `
--id JanDeDobbeleer.OhMyPosh `
--source winget `
--exact `
--verbose-logs
依然:
Successfully installed
查看日志后发现 Winget 下载的是:
install-x64.msix
安装过程使用的是 MSIX/AppX。
Winget 日志里甚至能看到:
StagePackageAsync
RegisterPackageByFullNameAsync
乍看起来一切正常。
但是安装结束后:
Get-AppxPackage | Where-Object Name -Like '*ohmyposh*'
仍然什么都没有。
AppX Deployment Event Log
于是直接查看 Windows AppX Deployment 日志:
Get-WinEvent `
-LogName 'Microsoft-Windows-AppXDeploymentServer/Operational' `
-MaxEvents 100 |
Where-Object {
$_.Message -match 'ohmyposh|96v55e8n804z4'
} |
Select-Object TimeCreated, Id, LevelDisplayName, Message |
Format-List
终于抓到了真正的错误:
Deployment Stage operation ... finished successfully.
Started deployment RegisterByPackageFullName operation ...
AppX Deployment operation failed for package
ohmyposh.cli_31.3.0.0_x64__96v55e8n804z4
with error 0x80070005.
0x80070005:
E_ACCESSDENIED
Access is denied.
而且连续多次安装,每次都是完全相同的结果。
能下载,但是不让装。
然后 Winget:
Successfully installed
嗯。
谢谢你,Winget。
F 这不是我的Windows
这是一台企业管理的 Windows 11。
具体是哪项企业策略导致 MSIX 注册被拒绝,我没有继续深挖。可能涉及 AppX/MSIX 策略、应用控制或者其他企业安全配置。
对我来说知道一点就行:不让装:
Oh My Posh 的 MSIX 能成功 Stage,但无法为当前用户完成 Register。
而且我只是想在PowerShell提示符看清楚repo的状态,并不打算和公司的 Windows 安全策较劲。
绕过 MSIX:直接安装 exe
查看 Oh My Posh 31.3.0 Release 后发现,除了:
install-x64.msix
官方还提供普通 Windows 可执行文件:
posh-windows-amd64.exe
于是直接创建自己的 bin:
$bin = "$HOME\bin"
New-Item -ItemType Directory -Force $bin | Out-Null
下载:
Invoke-WebRequest `
-Uri "https://github.com/JanDeDobbeleer/oh-my-posh/releases/download/v31.3.0/posh-windows-amd64.exe" `
-OutFile "$bin\oh-my-posh.exe"
为了保险,再验证 SHA256:
Get-FileHash "$bin\oh-my-posh.exe" -Algorithm SHA256
31.3.0 x64 executable 对应的 SHA256 是:
CA755EA573FA0E88FF60556E8EE6CC756F361C0C223883225318A40B2DED2392
可以用下面的命令自动比对,避免只看一眼输出:
$expected = "CA755EA573FA0E88FF60556E8EE6CC756F361C0C223883225318A40B2DED2392"
$actual = (Get-FileHash "$bin\oh-my-posh.exe" -Algorithm SHA256).Hash
if ($actual -ne $expected) { throw "SHA256 不匹配:$actual" }
"SHA256 验证通过:$actual"
然后直接运行:
& "$bin\oh-my-posh.exe" version
成功。
加入 User PATH
把 $HOME\bin 加进用户 PATH。下面会保留已有用户 PATH,并避免重复添加:
$bin = "$HOME\bin"
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
if (($userPath -split ';') -notcontains $bin) {
[Environment]::SetEnvironmentVariable(
'Path',
($userPath.TrimEnd(';') + ';' + $bin),
'User'
)
}
当前 PowerShell session 临时补上:
$env:Path += ";$bin"
现在:
oh-my-posh version
正常。
整个过程不需要 MSIX、不需要 AppX registration,也不需要管理员权限。
配置 PowerShell Profile
我原来的 $PROFILE 已经使用 posh-git。前面初始化 Profile 的命令因为 Oh My Posh 安装失败而暂时无法生效;现在 exe 已能通过 PATH 找到,保留模块导入并在后面初始化 prompt:
Import-Module posh-git
所以保留它,然后让 Oh My Posh 在后面接管 prompt:
Import-Module posh-git
# Initialize Oh My Posh
oh-my-posh init pwsh --config "jandedobbeleer" | Invoke-Expression
重新加载:
. $PROFILE
完成。
G 最后的经验
这次最大的坑其实不是 Oh My Posh,而是:
不要过度相信包管理器最后打印出来的 Successfully installed。
如果 Winget 声称安装成功,但:
winget list
查不到,
Get-Command
也找不到,
那么问题可能已经发生在 installer/package registration 层,而不是 PATH。
对于 MSIX/AppX,下面这个日志尤其值得记住:
Get-WinEvent `
-LogName 'Microsoft-Windows-AppXDeploymentServer/Operational' `
-MaxEvents 100
这次 Winget 的日志告诉我:
我成功调用了安装流程。
而 AppX Deployment 的日志告诉我:
不,你没有。
后者显然更接近事实。
至于 Oh My Posh——它本质上就是一个 CLI executable。
既然企业 Windows 不愿意让我注册它的 MSIX,那就把 oh-my-posh.exe 扔进 $HOME\bin。
问题解决。
有时候最好的企业 Windows troubleshooting,就是及时停止 troubleshooting 企业 Windows。
好了。感谢看到这里,看过就等于会了。❤️
Am 彩蛋
我好傻啊!我直接在WSL里面装powershell不就行了吗,WSL里面装什么都没人管。费这么大劲瞎折腾。
sudo apt update
sudo apt install -y powershell
pwsh
评论