Управление кодированием перенаправленного вывода команды консоли win

1059
user3528651

Вот что я хочу сделать:

Перенаправление правильно вывода консольных приложений (я использую термин команду в остальной части сообщения) в файл с 1252 кодированием (чтобы сделать его доступным для чтения из любого блокнота мягких в конфигурации по умолчанию.

Что я наблюдал:

Chcp эффективен с внутренними командами и некоторыми внешними командами (последние)

Прежде всего стоит отметить, что CHCP работает по-разному под Win7 и Win 10.

Если следующий пакет запускается из командной строки cmd, вы можете заметить, что выходные данные команды правильно отображаются в консоли win10, тогда как консоль win7 плохо отображает символы из ASCII.

for /f "tokens=2 delims=:" %%G in ('chcp') do Set _cp_=%%G chcp 1252 @echo test an internal command dir @echo test an external (recent) command: Robocopy robocopy .\ .\ /L @echo test an external (legacy) command: Xcopy xcopy test.txt 2>&1 chcp %_cp_% echo end of test.cmd batch  

Кстати, мне интересно узнать, что вызывает такую ​​разницу, хотя на самом деле это не цель этого сообщения, и поскольку это легко исправить, добавив ps invoke «powershell [console] :: outputencoding = [system.text.encoding] :: getencoding (850) »в пакете после 1-й команды chcp.

Независимо от реальной проблемы, когда пакетный вывод перенаправляется в файл: test.cmd> test.txt.

В этом случае результат будет одинаковым для любой ОС. Выходные данные внутренних команд и новых внешних команд (Robocopy, Bcdedit и т. Д.) Должным образом кодируются 1252. Устаревшие команды (xcopy, chcp и т. Д.) - нет (вывод в кодовой странице OEM). Короче говоря, на большинство команд не влияет CHCP или эквивалентное изменение [консоли] через powershell.

Различные предположения об этом беспорядке:

  1. Устаревший код команды основан на CRT, тогда как внутренние и последние внешние команды используют Win32 API. Это основано на последнем разделе, касающемся разработки консольного приложения от MSDN Globalization, шаг за шагом !

  2. Поскольку, по крайней мере, win10 отображает в консоли (одинаковую кодировку для всех выходных данных команды) и сохраняет файл по-разному (выходная кодировка изменяется в зависимости от команды), потоки вывода / ввода могут обрабатываться по-разному в зависимости от типа дескрипторов, на которые они указывают. Консольные функции могут использоваться для отображения и функций файла ввода / вывода в случае перенаправления. Спекуляция на основе высокоуровневых консольных функций ввода и вывода !

  3. MS рекомендует код консольных приложений, заставляет OEM-кодировку выходного потока. Ссылка Проблемы консольного приложения Если в коде внешних команд применяется предложение MS, которое может объяснить, почему перенаправление их выходных потоков в файл всегда кодируется OEM_CP независимо от того, применяется ли кодовая страница консоли. Как ни странно, readfile и writefile не упоминаются среди функций, затронутых SetFileApisToOEM

Наконец, я не знаю, заключается ли разница между устаревшими и недавно введенными командами в том, что их код соответствует предложению MS и просто потому, что строковые литералы кодируются как OEM против ANSI.

Возможные решения / обходной путь

Если 3 правильно, их, безусловно, очень мало. Можно изменить значение ключа реестра HKLM \ system \ currentset \ control \ NLS \ codepage OEMCP = 1252. Это небезопасно (не пытайтесь установить Unicode 65001, ваша система может отказаться от загрузки) и неудобно (необходима перезагрузка). Или, заполнив файл только OEM-кодированным содержимым и перекодировав файл с помощью сценария PS в конце пакета. Простой, но не очень элегантный, если к файлу нужно периодически обращаться и проверять.

Если 2 верно, может существовать функция, которая управляет кодированием файловых функций ввода-вывода readfile и writefile .

Если 1 верно, то должна быть возможность контролировать международные настройки или культуру текущего сеанса пользователя и, таким образом, контролировать кодовую страницу приложения CRT. Начиная с Win8, это возможно с помощью Powershell Configure International Settings в Windows . Приложения командной строки также могут выполнять такие вещи . Как бы то ни было, сложность здесь заключается в создании «культуры» с кодовой страницей OEM, установленной на 1252, так как ее нет в предопределенном наборе .

Даже если нет эффективного решения по этому вопросу, не стесняйтесь поделиться своими знаниями по этой теме. Мне просто любопытно понять, как MS реализовала это.

2
Какое отношение `bash` имеет к этому вопросу? Пожалуйста, удалите тег, если вы не можете объяснить. DavidPostill 8 лет назад 0
Ваш тестовый скрипт на Windows 7 здесь не отображает ничего странного. DavidPostill 8 лет назад 0
Извините за тег bash на самом деле ничего не делать. Тег был предложен мне, и я прочитал партию. На моем Win7 локализованном fr-fr, если я запускаю тестовый скрипт, все символы, отличные от Ascii, отображаются плохо: вот результат первых команд:> chcp 1252 Page dedes active ** **: 1252 test внутренней команды> dir Le Объем d le lecteur C s ** Æ ** наименование системного номера ** Ú ** ro s s Ú Ú ** Rie du Volume Est XXX user3528651 8 лет назад 0
Ах. Не могу помочь тебе тогда. У меня есть английская версия Windows без забавных персонажей;) DavidPostill 8 лет назад 0
: Не берите в голову, но да, я забыл упомянуть все, что имеет смысл только для систем вне en-US (или аналогичных) локалей и использования глифов, отличающихся от символов ASCII на их местном языке user3528651 8 лет назад 0
[Этот вопрос и мой ответ] (http://superuser.com/q/1056614/380318) больше говорят об изменении PowerShell, на которое вы ссылались, если кому-то еще это интересно. Ben N 8 лет назад 0

0 ответов на вопрос