Мне нужно декодировать стандартный вывод PowerShell, вызываемый из Python, в строку Python.
Моя конечная цель - получить в виде списка строк имена сетевых адаптеров в Windows. Моя текущая функция выглядит следующим образом и хорошо работает в Windows 10 с английским языком:
def get_interfaces():
ps = subprocess.Popen(['powershell', 'Get-NetAdapter', '|', 'select Name', '|', 'fl'], stdout = subprocess.PIPE)
stdout, stdin = ps.communicate(timeout = 10)
interfaces = []
for i in stdout.split(b'\r\n'):
if not i.strip():
continue
if i.find(b':')<0:
continue
name, value = [ j.strip() for j in i.split(b':') ]
if name == b'Name':
interfaces.append(value.decode('ascii')) # This fails for other users
return interfaces
У других пользователей разные языки, поэтому для некоторых из них value.decode('ascii')
не работает. Например. один пользователь сообщил, что переход на decode('ISO 8859-2')
хорошо работает для него (так что это не UTF-8). Как узнать кодировку для декодирования байтов стандартного вывода, возвращаемых при вызове PowerShell?
UPDATE
После некоторых экспериментов я еще больше растерялся. Кодовая страница в моей консоли, возвращаемая chcp
, равна 437. Я изменил имя сетевого адаптера на имя, содержащее символы не-ASCII и не-cp437. В интерактивном сеансе PowerShell, в котором запущен Get-NetAdapter | select Name | fl
, он правильно отображал имя, даже не символ CP437. Когда я вызывал PowerShell из Python, не-ASCII-символы были преобразованы в самые близкие ASCII-символы (например, ā в a, ž в z), и .decode(ascii)
работал хорошо. Может ли это поведение (и, соответственно, решение) зависеть от версии Windows? Я на Windows 10, но пользователи могут быть на старых Windows до Windows 7.