Изменить кодировку в командной строке Windows

Обновлено: 21.11.2024

Информация о кодировках символов в окнах командной строки.

Симптомы

В выводе программы командной строки (например, KPScript) некоторые специальные символы отображаются правильно, а некоторые нет.

При перенаправлении вывода в файл TXT с помощью оператора консоли '>' и открытии файла TXT в текстовом редакторе специальные символы искажаются.

Эти проблемы обычно возникают только в Windows, а не в Linux (поскольку Linux обычно использует кодировку UTF-8).

Причина

Эти кодовые страницы OEM поддерживают не все символы. Они включают небольшое подмножество иностранных символов (например, кодовая страница 437 США включает некоторые греческие символы), поэтому некоторые специальные символы правильно отображаются в окне командной строки. Однако редко используемые символы не могут быть закодированы.

При перенаправлении вывода в файл TXT с помощью оператора консоли ' > ' файл TXT использует ту же кодировку, что и окно командной строки. Текстовые редакторы обычно не используют кодовые страницы OEM и поэтому неправильно отображают специальные символы (даже те, которые правильно отображаются в окне командной строки).

Поиск кодовой страницы. Вы можете узнать, какую кодовую страницу использует ваше окно командной строки, введя ' Chcp ' (без каких-либо параметров).

Слабое решение: хороший текстовый редактор

Самое простое решение — сообщить текстовому редактору, какую кодовую страницу использует файл TXT. После этого все символы, поддерживаемые кодовой страницей, загружаются/отображаются правильно.

Недостаток этого решения заключается в том, что символы за пределами кодовой страницы консоли теряются.

Каждый расширенный текстовый редактор поддерживает выбор кодовой страницы; несколько примеров:

  • PSPad. В меню "Формат" нажмите "OEM", затем откройте файл TXT (важно выбрать "OEM" перед открытием файла TXT).
  • Блокнот2. Откройте файл TXT и выберите кодовую страницу в разделе «Файл» → «Кодировка» → «Перекодировать».
  • Блокнот++. Откройте файл TXT и выберите кодовую страницу в разделе «Кодировка» → «Наборы символов».
  • Майкрософт Visual Studio. Перейдите «Файл» → «Открыть» → «Файл», выберите файл TXT, щелкните стрелку раскрывающегося списка справа от кнопки «Открыть» в диалоговом окне выбора файла, выберите «Открыть с помощью», выберите «Исходный код (текст)». Редактор с кодировкой", выберите правильную кодовую страницу и нажмите "ОК".

Рекомендуемое решение: изменить кодовую страницу консоли

Кодировку символов консоли можно изменить на UTF-8, которая определяется кодовой страницей 65001 (в системах Windows). UTF-8 позволяет кодировать все символы Unicode, т.е. поддерживаются специальные символы всех языков.

Чтобы изменить кодовую страницу на UTF-8, выполните следующую команду:

Это прекрасно работает в Windows 7 и более поздних версиях. Старые операционные системы могут не поддерживать его.

Команда должна быть выполнена в окне командной строки перед запуском команды, которая перенаправляет вывод в файл TXT. Windows не сохраняет выбранную кодовую страницу, поэтому команду смены кодовой страницы необходимо выполнять в каждом окне командной строки отдельно.

Выходной файл TXT будет закодирован с использованием UTF-8. Эта кодировка поддерживается практически всеми текстовыми редакторами. UTF-8 обычно определяется автоматически, т.е. вам не придется выбирать кодировку/кодовую страницу вручную; вы можете "просто открыть" файл.

После изменения кодировки на UTF-8 специальные символы могут неправильно отображаться в окне командной строки (но нормально записываются в файл TXT), поскольку растровый шрифт по умолчанию не поддерживает эти символы. В этом случае выберите другой шрифт (щелкнув значок окна командной строки → «Свойства»), например, «Консоли» или «Консоль Lucida».

PowerShell

При использовании Windows PowerShell вместо стандартного окна командной строки файл TXT всегда будет кодироваться с использованием UTF-16 LE, независимо от того, какая кодовая страница консоли выбрана. PowerShell автоматически преобразует выходные данные программы командной строки из текущей активной кодовой страницы консоли в представление UTF-16 LE. Таким образом, PowerShell не сохраняет волшебным образом специальные символы. Программа командной строки может выводить только те символы, которые можно закодировать с помощью текущей активной кодовой страницы консоли. Таким образом, рекомендуется использовать решение Chcp 65001, описанное выше, и для PowerShell.

Кодировка 866, установленная по умолчанию в cmd.exe Windows, бедна и неудобна по сравнению с великолепным Unicode.

Можно ли установить Unicode по умолчанию или заменить cmd.exe на другую консоль и сделать его по умолчанию, чтобы программы использовали его вместо cmd.exe?

Я так понимаю, что chcp 65001 меняет кодировку только в работающей консоли. Я хочу изменить кодировку на системном уровне.

866 — это кодовая страница для кириллицы. Его изменение вполне может привести к поломке любой старой программы консольного режима, которая ожидает, что эта страница будет страницей по умолчанию. Это не значит, что вы не заметите, вы больше не сможете прочитать вывод программы.

В cmd.exe нет такой вещи, как кодировка Unicode. chcp 65001 обеспечивает некоторое декодирование UTF-8, но оно очень примитивно и не обеспечивает правильного ввода.

3 ответа 3

После того, как я попробовал решение Альгирдаса, у меня произошел сбой Windows (Win 7 Pro 64bit), поэтому я решил попробовать другое решение:

  1. Начать выполнение (Win+R)
  2. Введите cmd /K chcp 65001

В основном вы получите то, что хотите. Чтобы запустить его с панели задач или из любого другого места, создайте ярлык (вы можете назвать его cmd.unicode.exe или как вам угодно) и измените его Target на C:\Windows\System32\cmd.exe /K chcp 65001 .

Можно ли автоматически добавить эту команду в пакетный файл? Я имею в виду вот так START cmd /K chcp 65001 START DTRé.xls

С кодовой страницей 65001 консоль в Windows 7 (не Windows 8+) неправильно возвращает количество декодированных широкосимвольных кодовых точек для записанной в нее UTF-8, а не количество записанных в нее байтов, которое WriteFile должен вернуться. Это заставляет приложения повторно пытаться записать то, что они ошибочно определяют как оставшуюся часть строки байтов, до тех пор, пока консоль не вернет, что все «байты» (фактически декодированные широкие символы) были записаны. Результат выглядит как конечный поток ненужных символов после каждой печати, содержащей символы, отличные от ASCII.

С кодовой страницей 65001 консоль во всех версиях Windows (даже новая консоль в Windows 10) не поддерживает ввод, отличный от ASCII. Размер рабочего буфера, который он использует для кодирования своего входного буфера Unicode, основан на системной кодовой странице ANSI, которая обычно составляет 1 байт на символ. Но не-ASCII UTF-8 составляет 2-4 байта на символ. Таким образом, в консоли происходит сбой кодирования ввода, отличного от ASCII. Однако ReadFile возвращает, что он «успешно» прочитал 0 байтов. Большинство программ интерпретируют это как EOF, и REPL/оболочка обычно завершает работу в этом случае.

Измените кодовую страницу активной консоли. Кодовая страница по умолчанию определяется языковым стандартом Windows.

Эта команда редко требуется, так как большинство программ с графическим интерфейсом и PowerShell теперь поддерживают Unicode. При работе с символами вне диапазона ASCII от 0 до 127 выбор кодовой страницы будет определять набор отображаемых символов.

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

Кодовая страница Страна/регион/язык
437 США кодовая страница по умолчанию в США
850 Многоязычный (Latin I) кодовая страница по умолчанию в большинстве стран Европы
852 Славянский (Latin II)
855 Кириллица (русская)
857 Турецкий
860 португальский
861 исландский
863 канадско-французский
865 Северный
866 Русский
869 Современный греческий
1252 W европейская латиница
65000 UTF-7 *
65001 UTF-8 *

Даже если вы используете CHCP для запуска консоли Windows с кодовой страницей Unicode, многие приложения будут считать, что по-прежнему применяется значение по умолчанию, например. Java требует параметр-Dfile: java -Dfile.encoding=UTF-8

Символы Unicode будут отображаться только в том случае, если текущий шрифт консоли содержит эти символы. Поэтому используйте шрифт TrueType, например Lucida Console, вместо растрового шрифта CMD по умолчанию.

Оболочка CMD (работает внутри консоли Windows)

CMD.exe поддерживает только две кодировки символов Ascii и Unicode (CMD/A и CMD/U)

Если вам нужна полная поддержка Unicode, используйте PowerShell. По-прежнему существует ОЧЕНЬ ограниченная поддержка юникода в оболочке CMD, конвейерная обработка, перенаправление и большинство команд по-прежнему поддерживают только ANSI. Работают только команды DIR, FOR /F и TYPE, они позволяют читать и записывать (UTF-16LE / BOM) файлы и имена файлов, но не более того.

Кодовые страницы

Количество поддерживаемых кодовых страниц было значительно увеличено в Windows 7.
Чтобы получить полный список кодовых страниц, поддерживаемых на вашем компьютере, запустите NLSINFO (Инструменты Resource Kit).

Файлы, сохраненные в Блокноте Windows, по умолчанию будут в формате ANSI, но также могут быть сохранены как Unicode UTF-16LE или UTF-8, а для файлов Unicode будут включать спецификацию.
Спецификация делает пакетный файл неисполняемым в Windows, поэтому пакетные файлы необходимо сохранять в кодировке ANSI, а не в кодировке Unicode.

Просмотр текущей кодовой страницы:
chcp

Измените кодовую страницу на Unicode/65001:
chcp 65001

«Помните, что нет кода быстрее, чем его отсутствие» ~ Taligent's Guide to Design Programs

В этом посте мы обсудим улучшения, которые мы вносим во внутренний текстовый буфер консоли Windows, что позволяет лучше хранить и обрабатывать текст Unicode и UTF-8.

Сообщения в серии статей о командной строке Windows:

Этот список будет обновляться по мере публикации новых сообщений:

Наиболее заметным аспектом терминала командной строки является то, что он отображает текст, выдаваемый вашей оболочкой и/или инструментами и приложениями командной строки, в сетке моноширинных ячеек – одна ячейка на символ/символ/глиф. . Отлично, это просто. Как это может быть сложно, ведь это всего лишь буквы? Неееет! Читайте дальше!

Текст есть текст есть текст. Или это?

Если вы говорите на языке, возникшем в Западной Европе (например, английском, французском, немецком, испанском и т. д.), скорее всего, ваш письменный алфавит довольно однороден: 10 цифр, 26 отдельных букв – заглавные и нижний регистр = всего 62 символа. Теперь добавьте около 30 символов пунктуации, всего вам понадобится около 95 символов. Но если вы из Восточной Азии (например, китайцы, японцы, корейцы, вьетнамцы и т. д.), вы, скорее всего, будете читать и писать текст с еще несколькими символами… всего более 7000!

Учитывая эту сложность, как компьютеры представляют, определяют, хранят, обмениваются/передают и отображают эти различные формы текста эффективным и стандартизированным/обычно понятным способом?

Вначале был ASCII

Рассвет современных цифровых вычислений был сосредоточен вокруг Великобритании и США, поэтому английский язык был преобладающим языком и используемым алфавитом.

Как мы видели выше, ~95 символов английского алфавита (и необходимые знаки препинания) могут быть индивидуально представлены с помощью 7-битных значений (0-127), с оставленным местом для дополнительных невидимых управляющих кодов.< /p>

В 1963 году Американский национальный институт стандартов (ANSI) опубликовал стандарт X3.4-1963 для Американского стандартного кода для обмена информацией (ASCII), который стал основой того, что мы сейчас знаем как стандарт ASCII.

… и у Microsoft плохая репутация из-за названий вещей 😉 Первоначальный стандарт X3.4-1963 оставил 28 значений неопределенными и зарезервированными для использования в будущем. Воспользовавшись случаем, Международный консультативный комитет по телеграфу и телефону (CCITT, от французского: Comité Consultatif International Téléphonique et Télégraphique) предложил изменить раскладку ANSI, из-за которой символы нижнего регистра отличались по битовому шаблону от символов верхнего регистра на всего один бит. Это упростило определение/сопоставление регистра символов и создание клавиатур и принтеров.

Со временем в некоторые символы и управляющие коды были внесены дополнительные изменения, пока мы не пришли к хорошо зарекомендовавшей себя таблице символов ASCII, которая поддерживается практически всеми современными вычислительными устройствами.

]4 7-битная таблица ASCII

Однако быстрое внедрение компьютеров в Европе поставило перед нами новую задачу: как представить текст на других языках, кроме английского. Например, как должны быть представлены буквы с диакритическими знаками, умлауты и дополнительные символы?

Но этого по-прежнему недостаточно для представления всех символов, глифов и символов, необходимых пользователям компьютеров по всему миру, многим из которых необходимо представлять и отображать дополнительные символы / глифы.

Итак, появились кодовые страницы.

Кодовые страницы — частичное решение

Кодовые страницы определяют наборы символов для «расширенных символов» от 0x80 до 0xff (и, в некоторых случаях, некоторых не отображаемых символов от 0x00 до 0x19). Выбрав другую кодовую страницу, Терминал может отображать дополнительные глифы для европейских языков и некоторые блочные символы (см. выше), текст CJK, текст на вьетнамском языке и т. д.

Однако написание кода для обработки/перестановки кодовых страниц, а также отсутствие какой-либо стандартизации для кодовых страниц в целом затрудняли обработку и отрисовку текста, приводили к возникновению ошибок и создавали серьезные проблемы взаимодействия и взаимодействия с пользователем.

Что еще хуже, 128 дополнительных глифов даже близко не обеспечивают достаточное количество символов для представления некоторых языков: например, в китайском языке средней школы используется 2200 идеограмм, еще несколько сотен используются в повседневной жизни, и более 7000 идеограмм. всего.

Очевидно, что кодовые страницы — дополнительные наборы из 128 символов — не являются масштабируемым решением этой проблемы.

Подход с кодовой страницей двухбайтового набора символов (DBCS) использует два байта для представления одного символа. Это дает адресуемое пространство 2 ^ 16 - 1 == 65 535 символов. Однако, несмотря на попытки стандартизировать японскую кодировку Shift JIS и кодировку EUC-JP, совместимую с ASCII переменной длины, кодировки кодовых страниц DBCS часто были пронизаны проблемами и не давали универсального решения проблемы кодирования текста. /p>

Что нам действительно было нужно, так это универсальный код для текстовых данных.

Введите, Юникод

Юникод — это набор стандартов, определяющих способ представления и кодирования текста.

Разработка Unicode началась в 1987 году инженерами компаний Xerox и Apple. Первоначальная спецификация Unicode-88 была опубликована в феврале 1988 года и с тех пор постоянно дорабатывалась и обновлялась, добавляя новые представления символов, дополнительную языковую поддержку и даже эмодзи 😊

Чтобы узнать больше об истории Unicode, прочтите это! Сегодня Unicode поддерживает до 1 112 064 допустимых «кодовых точек», каждая из которых представляет один символ / символ / глиф / идеограмму / и т. д. Это должно обеспечить множество адресуемых кодовых точек в будущем, особенно с учетом того, что «Юникод 11 в настоящее время определяет 137 439 символов, охватывающих 146 современных и исторические сценарии, а также несколько наборов символов и эмодзи» [источник: Википедия, октябрь 2018 г.]

«1,2 миллиона кодовых точек должно быть достаточно для всех» — источник: Рич Тернер, октябрь 2018 г. Текстовые данные Unicode могут быть закодированы разными способами, каждый со своими сильными и слабыми сторонами:

Во многом благодаря своей гибкости и эффективности хранения/передачи UTF-8 стал преобладающим механизмом кодирования текста в Интернете: на сегодняшний день (октябрь 2018 г.) 92,4 % всех веб-страниц закодированы в UTF-8!< /p>

]16 Популярность кодировки UTF-8 для веб-страниц (источник: Википедия)

Поэтому ясно, что все, что обрабатывает текст, должно как минимум поддерживать текст UTF-8.

Увы, консоль Windows (в настоящее время) не может поддерживать текст UTF-8!

Консоль Windows была создана на заре Windows, еще до того, как появился сам Unicode! Тогда было принято решение представлять каждый текстовый символ как 16-битное значение фиксированной длины (UCS-2). Таким образом, текстовый буфер консоли содержит 2-байтовые значения wchar_t на ячейку сетки, размер x столбцов на y строк.

Хотя эта конструкция поддерживает консоль более 25 лет, быстрое внедрение UTF-8 начало вызывать проблемы:

Например, одна из проблем заключается в том, что, поскольку UCS-2 представляет собой 16-битную кодировку с фиксированной шириной, она не может представлять все кодовые точки Unicode.

Еще одна связанная, но отдельная проблема с консолью Windows заключается в том, что, поскольку GDI используется для рендеринга текста консоли, а GDI не поддерживает резервный шрифт, консоль не может отображать глифы для кодовых точек, которые не существуют в выбранном в данный момент шрифте. !

Font-fallback — это возможность динамического поиска и загрузки шрифта, похожего на текущий выбранный шрифт, но содержащего глиф, отсутствующий в текущем выбранном шрифте. Эти комбинированные проблемы объясняют, почему консоль Windows не может (в настоящее время) отображать многие сложные китайские иероглифы и не может отображать эмодзи.

Эмодзи? СРОЧНО? На первый взгляд это может показаться тривиальным, но это проблема, поскольку некоторые инструменты теперь отображают эмодзи, например, для обозначения результатов теста, а исходный код некоторых языков программирования поддерживает/требует Unicode, включая эмодзи!

Атрибуты текста

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

Эти атрибуты должны храниться эффективно и быстро: нет необходимости хранить фоновую информацию и информацию об основном плане для каждой ячейки отдельно, тем более что большинство консольных приложений/инструментов выводят довольно однородно окрашенный текст, но сохранение и извлечение атрибутов не должно излишне снижать производительность рендеринга. .

Давайте углубимся и выясним, как со всем этим справляется консоль! 😊

Как обсуждалось в предыдущем посте этой серии, команда разработчиков консоли была занята капитальным ремонтом внутренних компонентов консоли Windows для последних нескольких выпусков Win10, тщательно модернизируя, разбивая на модули, упрощая и улучшая код и функции консоли… при этом не жертвуя заметно производительность, а не изменение текущего поведения.

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

Главная проблема, которую нужно было решить, заключалась в том, что консоль ранее сохраняла текстовые данные каждой ячейки в виде 2-байтовых значений UCS-2 фиксированной длины wchar_t.

Для полной поддержки всех символов Unicode нам требовался более гибкий подход, не добавляющий заметных затрат на обработку или память в общем случае, но способный динамически обрабатывать дополнительные байты текстовых данных для ячеек, содержащих многобайтовые символы Unicode.< /p>

Мы рассмотрели несколько подходов, создали прототипы и измерили некоторые из них, что помогло нам исключить некоторые потенциальные подходы, которые оказались неэффективными в реальных условиях.

Добавление поддержки Unicode

]21 Архитектура текстового буфера консоли

Сверху (синие прямоугольники оригинального буфера):

  • ScreenInfo — содержит информацию об области просмотра и т. д. и содержит TextBuffer
    • TextBuffer — представляет текстовую область консоли в виде набора строк
      • Строка — уникальное представление каждой строки CharRow в консоли и атрибутов форматирования, применяемых к каждой строке
        • CharRow – содержит набор ячеек CharRowCell, а также логику и состояние для обработки переноса строк и навигации.
          • CharRowCell – содержит фактический текст ячейки и байт DbcsAttribute, содержащий флаги, относящиеся к ячейке.

          В реализацию буфера консоли было внесено несколько ключевых изменений (обозначены оранжевым цветом на диаграмме выше), в том числе:

          1. Атрибут CharRowCell::DbcsAttribute консоли хранит информацию о форматировании о том, насколько широкими являются текстовые данные для символов DBCS. Не все биты использовались, поэтому был добавлен дополнительный флаг, указывающий, превышает ли длина текстовых данных для ячейки один 16-битный wchar_t. Если этот флаг установлен, консоль будет извлекать текстовые данные из хранилища UnicodeStorage .
          2. Добавлено хранилище UnicodeStorage, которое содержит сопоставление координат с набором 16-битных значений wchar. Это позволяет буферу хранить произвольное количество значений wchar для каждой отдельной ячейки в консоли, в которой должны храниться дополнительные текстовые данные Unicode, гарантируя, что консоль останется невосприимчивой к расширению области действия и диапазона текстовых данных Unicode в будущем. А поскольку UnicodeStorage — это карта, затраты на поиск лишнего текста постоянны и быстры!

          Итак, представьте, что ячейке нужно отобразить ухмыляющийся смайлик Unicode: 😀 Представление этого смайлика в байтах (с прямым порядком байтов): 0xF0 0x9F 0x98 0x80 или словами: 0x9FF0 0x8098 . Очевидно, что этот глиф эмодзи не помещается в один 2-байтовый wchar_t. Таким образом, в новом буфере будет установлен флаг переполнения DbcsAttribute CharRowCell, указывающий, что консоль должна искать данные в кодировке UTF-16 для тех, которые хранятся в контейнере карты UnicodeStorage.

          Ключевой момент, который следует отметить в отношении этого подхода, заключается в том, что нам не нужно дополнительное хранилище, если символ может быть представлен в виде одного 8/16-битного значения: нам нужно только хранить дополнительный «переполненный» текст, когда это необходимо. Это гарантирует, что в наиболее распространенном случае — при хранении символов ASCII и более простых символов Unicode — мы не увеличиваем объем потребляемых данных и не снижаем производительность.

          Если вы используете Windows 10 October 2018 Update (сборка 1809), вы уже используете этот новый буфер!

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

          Мы также работаем над дальнейшим улучшением реализации буфера в последующих обновлениях ОС (и в сборках Insider, которые предшествуют каждому выпуску ОС).

          Вышеуказанные изменения позволяют хранить только одну кодовую точку на CharRowCell . Более сложные глифы, для которых требуется несколько кодовых точек, пока не поддерживаются, но мы работаем над добавлением этой возможности в будущем выпуске ОС.

          Текущие изменения также не охватывают то, что требуется для нашего «режим обработанного ввода», который представляет редактируемую строку ввода для таких приложений, как CMD.exe.Мы планируем и активно обновляем код для всплывающих окон, псевдонимов команд, истории команд и самой редактируемой строки ввода, чтобы также поддерживать полную поддержку Unicode.

          И пока не пытайтесь отображать смайлики — для этого требуется новый механизм рендеринга, поддерживающий резервный шрифт — возможность динамически находить, загружать и отображать глифы из шрифтов, отличных от текущего выбранного шрифта. И это тема для отдельного поста в другой раз 😉.

          Скоро ждите новых сообщений!

          Мы с нетерпением ждем ваших мыслей — не стесняйтесь выключать звук ниже или пинговать Рича в Твиттере.

          Читайте также: