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

如何在Azure DevOps中用PowerShell正确打印Unicode字符串

问题描述

我需要将标准输出(stdout)记录到Azure DevOps任务的日志中。以下是我的PowerShell脚本片段:

$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "msiexec.exe"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = "/i `"<<my-msi-file>>`" REBOOT=ReallySuppress /L*v+ $logFile /qn"
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$stdout = $p.StandardOutput.ReadToEnd()
Write-Host "stdout: $stdout"

我能获取到输出,但显示异常,无法正常复制粘贴,大致显示为:

Example text

如何让文本正常显示为“Example text”?

补充说明:
若要在标准输出中获取错误文本,只需将<<my-msi-file>>替换为不存在的文件名,例如c:\dev\null\nofile.msi。


解决方案

这是编码不匹配导致的问题:msiexec.exe的标准输出采用**UTF-16LE(Unicode)**编码,但PowerShell默认用UTF-8解析输出,使得每个字符间被插入空字节,最终显示为带间隔符号的乱码。

你可以通过两种方式修复:

方式1:读取时指定编码

替换脚本中读取输出的代码:

# 替换原有的 $stdout = $p.StandardOutput.ReadToEnd()
$stdout = [Console]::OutputEncoding.GetString($p.StandardOutput.BaseStream.ToArray())

方式2:配置ProcessStartInfo的输出编码

在创建ProcessStartInfo时直接指定编码:

$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "msiexec.exe"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
# 添加编码设置,匹配msiexec的输出编码
$pinfo.StandardOutputEncoding = [System.Text.Encoding]::Unicode
$pinfo.Arguments = "/i `"<<my-msi-file>>`" REBOOT=ReallySuppress /L*v+ $logFile /qn"
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$stdout = $p.StandardOutput.ReadToEnd()
Write-Host "stdout: $stdout"

两种方法都能让输出正常显示,解决乱码和无法复制的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 13:43:26