You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PowerShell中捕获ProcessStartInfo标准输出并做字符串比较

解决msiexec输出字符串比较失败的问题

问题根源分析

  1. 空值判断失效:$p.StandardOutput.ReadToEnd()即使没有输出,返回的也是**空字符串("")**而非$null,再经过Out-String处理后依然是空字符串,所以用$stdout -eq $null永远不会成立。
  2. 特殊格式字符串匹配失败:你看到的每个字母间带空格的输出,是因为msiexec的错误输出采用UTF-16LE(Unicode)编码,但PowerShell默认用系统ANSI编码读取,导致字符解析错乱,出现多余空格。

具体解决步骤

1. 正确判断空输出

用以下两种方式替代$stdout -eq $null:

  • 检查空字符串或null:[string]::IsNullOrEmpty($stdout)
  • 直接匹配空字符串:$stdout -eq ''

2. 修正输出编码,解决字符串格式错乱

在创建ProcessStartInfo时,指定StandardOutputEncoding和StandardErrorEncoding为UTF-16LE(对应[System.Text.Encoding]::Unicode),确保正确解析msiexec的输出。

修改后的完整代码

$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = 'msiexec'
# 指定编码为UTF-16LE,匹配msiexec的输出编码
$pinfo.StandardOutputEncoding = [System.Text.Encoding]::Unicode
$pinfo.StandardErrorEncoding = [System.Text.Encoding]::Unicode
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = "/x {22AD1D41-EDA0-4387-BF16-9045CE734FAD} /quiet /norestart /l*v `"C:\temp\msi123_MSI_UNINSTALL.log`""
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
# 无需再用Out-String,ReadToEnd()已经返回正确格式的字符串,Trim()去除首尾空白
$stdout = $p.StandardOutput.ReadToEnd().Trim()
$stderr = $p.StandardError.ReadToEnd().Trim()

3. 正确匹配目标字符串

编码修正后,直接用正常的字符串进行比较即可:

$targetMsg = "This action is only valid for products that are currently installed."
if ($stdout -eq $targetMsg -or $stderr -eq $targetMsg) {
    # 处理未安装产品的情况
    Write-Host "目标产品未安装,无法执行卸载操作"
}

额外提示

  • msiexec的错误信息有时会输出到stderr而非stdout,建议同时检查两个输出流
  • 使用Trim()可以去除输出中可能存在的首尾换行符或空格,避免因多余空白导致匹配失败

内容的提问来源于stack exchange,提问作者Bbb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 16:48:12