[issue45382] platform() is not able to detect windows 11

Eryk Sun report at bugs.python.org
Mon Jan 24 12:47:39 EST 2022


Eryk Sun <eryksun at gmail.com> added the comment:

> It's *very* unlikely you'll ever get output that doesn't fit into MBCS,

When writing to a pipe, wmic.exe hard codes using the process OEM code page (i.e. CP_OEMCP). If it matters, running wmic.exe with subprocess should use encoding='oem' instead of text=True.

That said, wmic.exe is deprecated. I suggest using PowerShell instead. For example:

    import os
    import json
    import subprocess

    cmd = 'Get-CimInstance Win32_OperatingSystem | Select Caption, Version | ConvertTo-Json'
    p = subprocess.run(f'powershell.exe -c "{cmd}"', capture_output=True, encoding=os.device_encoding(1))
    result = json.loads(p.stdout)

PowerShell uses the console's output code page (i.e. os.device_encoding(1)) when writing to stdout, even if it's a pipe. (If PowerShell is run without a console via DETACHED_PROCESS, then it outputs nothing to stdout.) The only way I know of to make PowerShell write UTF-8 to stdout when it's a pipe is by temporarily changing the console output code page. Assuming the current process has a console, you have to first get the current code page with GetConsoleOutputCP(). Change the code page to UTF-8 via SetConsoleOutputCP(CP_UTF8). Run the PowerShell command. Finally, restore the original code page.

Maybe subprocess should provide a context manager to set the console code pages before a call, and restore the previous console code pages and console modes after a call completes. That's what CLI shells such as CMD do when running an external program.

----------

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue45382>
_______________________________________


More information about the Python-bugs-list mailing list