使用Python子进程打开Powershell导致stdout出现编码错误

问题描述 投票:0回答:1

我正在尝试从 python 运行 Powershell 脚本并打印输出,但输出包含特殊字符“é”。

process = subprocess.Popen(\[r'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe',  'echo é'\], stdout=subprocess.PIPE)
print(process.stdout.read().decode('cp1252'))

返回“,”

process = subprocess.run(r'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe echo é', stdout=subprocess.PIPE)
print(process.stdout.decode('cp1252'))

返回“,”

print(subprocess.check_output(r'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe echo é').decode('cp1252'))

返回“,”

除了子进程之外还有其他方法吗,或者我应该使用不同的编码?

UTF-8 对 é 给出错误,但对 ® 返回“r”。 UTF-16-le 给出错误“UnicodeDecodeError:'utf-16-le'编解码器无法解码位置 2 中的字节 0x0a:截断的数据”。

python powershell character-encoding subprocess
1个回答
0
投票

PowerShell CLI 使用活动控制台窗口的代码页,如 chcp

 的输出所示,默认情况下是旧系统区域设置的 
OEM 代码页,例如(用Python术语表达)cp437
.
相比之下,
cp1252
 是一个 
ANSI 代码页。

一种选择是简单地

通过 WinAPI 查询控制台窗口的活动(输出)代码页并使用返回的编码

import subprocess from ctypes import windll # Get the console's (output) code page, which the PowerShell CLI # uses to encode its output. cp = windll.kernel32.GetConsoleOutputCP() process = subprocess.Popen(r'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe echo é', stdout=subprocess.PIPE) # Decode based on the active code page. print(process.stdout.read().decode('cp' + str(cp)))
但是,请注意 OEM 代码页限制为 256 个字符;而 

é

 
可以 表示为 CP437,例如其他 Unicode 字符,例如
,则不能。

因此

robust选项是(暂时)将控制台输出代码页设置为65001

,即UTF-8
:

import subprocess from ctypes import windll # Save the current console output code page and switch to 65001 (UTF-8) previousCp = windll.kernel32.GetConsoleOutputCP() windll.kernel32.SetConsoleOutputCP(65001) process = subprocess.Popen(r'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe echo é€', stdout=subprocess.PIPE) # Decode as UTF-8 print(process.stdout.read().decode('utf8')) # Restore the previous output console code page. windll.kernel32.SetConsoleOutputCP(previousCp)
注:

© www.soinside.com 2019 - 2024. All rights reserved.