Note: The following Python 3+ solutions work in principle, however:
Due to a bug in powershell.exe
, the Windows PowerShell CLI, the current console window switches to a raster font (potentially with a different font size), which does not support most non-extended-ASCII-range Unicode characters. While visually jarring, this is merely a display (rendering) problem; the data is handled correctly; switching back to a Unicode-aware font such as Consolas
reveals the correct output.
By contrast, pwsh.exe
, the PowerShell (Core) (v6+) CLI does not exhibit this problem.
Option A: Configure both the console and Python to use UTF-8 character encoding before executing your script:
Now, your original code should work as-is (except for the display bug).
Option B: Temporarily switch to UTF-8 for the PowerShell call:
import sys, ctypes, subprocess
# Switch Python's own encoding to UTF-8, if necessary
# This is the in-script equivalent of setting environment var.
# PYTHONUTF8 to 1 *before* calling the script.
sys.stdin.reconfigure(encoding='utf-8'); sys.stdout.reconfigure(encoding='utf-8'); sys.stderr.reconfigure(encoding='utf-8')
# Enclose the PowerShell call in `chcp` calls:
# * Change to the UTF-8 code page (65001),
# * Execute the PowerShell command (which then outputs UTF-8)
# * Restore the original OEM code page.
command = "chcp 65001 >NUL & powershell ls ~/Desktop & chcp " + str(ctypes.cdll.kernel32.GetConsoleOutputCP()) + ' >NUL'
# Note:
# * `shell=True` ensure that the command is invoked via cmd.exe, which is
# required, now that we're calling *multiple* executables and use output
# redirections (`>NUL`)
print(subprocess.run(command.split(), stdout=subprocess.PIPE, shell=True).stdout.decode())
[1] This isn't strictly necessary just for correctly decoding PowerShell's output, but matters if you want to pass that output on from Python: Python 3.x defaults to the active ANSI(!) code page for encoding non-console output, which means that Hebrew characters, for instance, cannot be represented in non-console output (e.g., when redirecting to a file), and cause the script to break.