程序inv.exe根据参数返回一些控制台数据。它看起来像一个 JSON/字典,但它是文本格式(打印输出)。当我简单地调用它而不尝试捕获输出时它就可以工作。
.\inv.exe getter segments
{28: 'Renda Fixa', 29: 'Renda Variável', ...
但是,如果我尝试捕获它,则不起作用:
$segmentsjson = .\inv.exe getter segments
$segmentsjson
{28: 'Renda Fixa', 29: 'Renda Vari�vel'....
$segmentsjson = .\inv.exe getter segments | ConvertFrom-Json
$segmentsjson
{"28": "Renda Fixa", "29": "Renda Variável"...
我尝试过的:
1. chcp 65001
2. $OutputEncoding = [System.Text.Encoding]::UTF8
3. [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
4. $OutputEncoding = [Console]::InputEncoding = [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding
5. .\inv.exe getter segments > test.txt
$segmentsjson = Get-Content "test.txt" -Encoding UTF8
6. .\inv.exe getter segments | Out-File -FilePath "output_temp.txt" -Encoding UTF-8
7. cmd /c inv.exe getter segments > test.txt
只有在 Windows 上的 PowerShell 中捕获或重定向外部程序输出时,字符编码问题才可能出现,因为某些 CLI(包括备受瞩目的 CLI,如 python.exe
和
node.exe
)使用 Unicode 版本
WriteConsole
打印到控制台时的 WinAPI 函数,其中所有字符均按预期打印。[1]
PowerShell 在将外部程序输出解码为 .NET 字符串时确实使用 [Console]::OutputEncoding
(
System.String
([string]
,在 PowerShell 术语中),其内部使用由内存中 UTF-16 代码组成的 Unicode 编码)单位 (System.Char
([char]
))。
如果
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
没有帮助,则意味着 inv.exe
的输出不是 UTF-8。
因此,您必须(暂时)设置
[Console]::OutputEncoding
以匹配 inv.exe
使用的实际字符编码,看起来
是旧系统区域设置的活动ANSI 编码,例如美国英语和西方语言上的 Windows-1252欧洲版本的 Windows:
$segmentsjson =
& {
$prevEnc = [Console]::OutputEncoding
# Set [Console]::OutputEncoding to that of the system's active ANSI code page.
[Console]::OutputEncoding =
if ($IsCoreCLR) { [Text.Encoding]::GetEncoding([int] (Get-ItemPropertyValue registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage ACP)) }
else { [Text.Encoding]::Default }
.\inv.exe getter segments
[Console]::OutputEncoding = $prevEnc
}
[1] 根据所选字体,并非所有 Unicode 字符都可以正确,但控制台缓冲区可以正确存储它们,因此您可以复制和粘贴它们而不会丢失信息。