如何解决Invoke-Item调用可变路径exe传/qn报错及提取注册表卸载GUID?
报错根因
Invoke-Item仅支持直接启动可执行文件本身,不支持接收拼接了运行参数的字符串作为输入,原脚本将路径和/qn参数拼接后传入Invoke-Item会触发参数识别错误。- 原方案通过遍历文件系统查找卸载程序的稳定性差,若应用安装路径自定义、目录结构变动就会匹配失败。
最优优化方案(基于厂商官方卸载逻辑)
直接读取注册表提取卸载GUID调用msiexec执行卸载,兼容性、稳定性远高于遍历文件的方案,完整脚本如下:
# 读取32位应用卸载注册表节点下的所有配置 $uninstallRegPath = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" $targetApp = Get-ItemProperty -Path $uninstallRegPath | Where-Object { # 替换为对应应用在控制面板中显示的正式名称即可,无需硬编码GUID $_.DisplayName -eq "你的应用官方显示名称" } if ($targetApp) { # 注册表子项名称就是对应卸载GUID $uninstallGuid = $targetApp.PSChildName # 调用msiexec执行静默卸载,等待执行完成 Start-Process -FilePath "msiexec.exe" -ArgumentList "/X$uninstallGuid /qn /norestart" -Wait -NoNewWindow Write-Host "卸载执行完成,退出码:$LASTEXITCODE" } else { Write-Host "未检测到目标应用安装记录" }
逻辑说明
- 若已知应用的卸载GUID固定为
{1D9F5D88-12AA-427F-8A33-DED71D60E4D9},可以直接在Where-Object中匹配$_.PSChildName -eq "{1D9F5D88-12AA-427F-8A33-DED71D60E4D9}"即可,无需匹配显示名。 - 使用
Start-Process传递参数可避免路径空格、特殊字符转义问题,比字符串拼接的执行方式稳定度更高。
原脚本修复方案(仍用installer.exe卸载)
如果必须沿用原遍历文件的逻辑,可修改执行部分的代码避免Invoke-Item报错:
# 匹配到多个结果时取第一个有效路径 $path_to_exe = Get-ChildItem -Path "C:\Program Files\ApplicationName" -Include "installer.exe" -Recurse | Where-Object { $_.FullName -match '\{(.*)\}' } | Select-Object -First 1 if ($path_to_exe) { $stdPath = Convert-Path $path_to_exe.PSPath # 用Start-Process单独传递可执行文件路径和参数 Start-Process -FilePath $stdPath -ArgumentList "/qn" -Wait -NoNewWindow }
内容的提问来源于stack exchange,提问作者user14998724
相关产品推荐
相关产品推荐

