WIX4.0.5制作的MSI中自定义Action执行脚本无法找到winget命令
问题分析
你的WIX自定义Action采用deferred模式+Impersonate=no配置,意味着脚本是通过系统账户(Local System)执行的,而非当前登录用户。这会导致两个核心问题:
- 系统账户的
PATH环境变量与普通用户不同,默认不包含winget的安装路径 - 若winget是用户级安装(而非系统级),系统账户无法访问用户目录下的winget实例
解决方案
1. 在PowerShell脚本中动态获取winget完整路径
winget通常安装在WindowsApps目录下,版本号会随更新变化,可通过动态查找的方式获取其完整路径:
修改后的PowerShell脚本:
# 动态查找x64版本winget路径 $wingetPath = Get-ChildItem -Path "C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_*_x64__8wekyb3d8bbwe" -Filter winget.exe -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName # 若x64未找到,尝试查找x86版本 if (-not $wingetPath) { $wingetPath = Get-ChildItem -Path "C:\Program Files (x86)\WindowsApps\Microsoft.DesktopAppInstaller_*_x86__8wekyb3d8bbwe" -Filter winget.exe -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName } # 验证winget是否存在 if (-not $wingetPath) { Write-Host "winget is not installed. Please install winget and try again." exit 1 } # 使用完整路径执行winget安装命令 try { & $wingetPath install --id=Microsoft.DotNet.DesktopRuntime.6 --accept-package-agreements --accept-source-agreements -e Write-Host "Desktop runtime installed successfully." } catch { Write-Host "Failed to install Desktop runtime." Write-Host $_.Exception.Message exit 1 }
2. 简化WIX自定义Action的命令行
将PowerShell的-Command参数替换为-File,避免脚本块的引号转义问题,让命令更清晰:
<CustomAction Id="RunDotNetInstallerTest" Directory="INSTALLFOLDER" ExeCommand="powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File ".\Scripts\dotnet-runtime-installer.ps1" *> C:\install-log.txt" Execute="deferred" Return="check" Impersonate="no" />
3. 额外注意事项
- 若安装包需要支持非管理员安装,需将
Impersonate设为yes,此时脚本会以当前用户身份执行,需确保用户有足够权限安装.NET Runtime - 确认
INSTALLFOLDER正确指向脚本所在目录,避免相对路径错误 - 可在脚本中添加
Write-Host $env:PATH输出,排查系统账户的PATH是否包含winget路径
内容的提问来源于stack exchange,提问作者envoydev
相关产品推荐
相关产品推荐

