Note:
-
This answer shows how to switch the character encoding in the Windows console to
(BOM-less) UTF-8 (code page65001
), so that shells such ascmd.exe
and PowerShell properly encode and decode characters (text) when communicating with external (console) programs with full Unicode support, and incmd.exe
also for file I/O.[1] -
If, by contrast, your concern is about the separate aspect of the limitations of Unicode character rendering in console windows, see the middle and bottom sections of this answer, where alternative console (terminal) applications are discussed too.
Does Microsoft provide an improved / complete alternative to chcp 65001 that can be saved permanently without manual alteration of the Registry?
As of (at least) Windows 10, version 1903, you have the option to set the system locale (language for non-Unicode programs) to UTF-8, but the feature is still in beta as of this writing.
To activate it:
- Run
intl.cpl
(which opens the regional settings in Control Panel) - Follow the instructions in the screen shot below.
-
This sets both the system’s active OEM and the ANSI code page to
65001
, the UTF-8 code page, which therefore (a) makes all future console windows, which use the OEM code page, default to UTF-8 (as ifchcp 65001
had been executed in acmd.exe
window) and (b) also makes legacy, non-Unicode GUI-subsystem applications, which (among others) use the ANSI code page, use UTF-8.-
Caveats:
-
If you’re using Windows PowerShell, this will also make
Get-Content
andSet-Content
and other contexts where Windows PowerShell default so the system’s active ANSI code page, notably reading source code from BOM-less files, default to UTF-8 (which PowerShell Core (v6+) always does). This means that, in the absence of an-Encoding
argument, BOM-less files that are ANSI-encoded (which is historically common) will then be misread, and files created withSet-Content
will be UTF-8 rather than ANSI-encoded. -
[Fixed in PowerShell 7.1] Up to at least PowerShell 7.0, a bug in the underlying .NET version (.NET Core 3.1) causes follow-on bugs in PowerShell: a UTF-8 BOM is unexpectedly prepended to data sent to external processes via stdin (irrespective of what you set
$OutputEncoding
to), which notably breaksStart-Job
— see this GitHub issue. -
Not all fonts speak Unicode, so pick a TT (TrueType) font, but even they usually support only a subset of all characters, so you may have to experiment with specific fonts to see if all characters you care about are represented — see this answer for details, which also discusses alternative console (terminal) applications that have better Unicode rendering support.
-
As eryksun points out, legacy console applications that do not «speak» UTF-8 will be limited to ASCII-only input and will produce incorrect output when trying to output characters outside the (7-bit) ASCII range. (In the obsolescent Windows 7 and below, programs may even crash).
If running legacy console applications is important to you, see eryksun’s recommendations in the comments.
-
-
-
However, for Windows PowerShell, that is not enough:
- You must additionally set the
$OutputEncoding
preference variable to UTF-8 as well:$OutputEncoding = [System.Text.UTF8Encoding]::new()
[2]; it’s simplest to add that command to your$PROFILE
(current user only) or$PROFILE.AllUsersCurrentHost
(all users) file. - Fortunately, this is no longer necessary in PowerShell Core, which internally consistently defaults to BOM-less UTF-8.
- You must additionally set the
If setting the system locale to UTF-8 is not an option in your environment, use startup commands instead:
Note: The caveat re legacy console applications mentioned above equally applies here. If running legacy console applications is important to you, see eryksun’s recommendations in the comments.
-
For PowerShell (both editions), add the following line to your
$PROFILE
(current user only) or$PROFILE.AllUsersCurrentHost
(all users) file, which is the equivalent ofchcp 65001
, supplemented with setting preference variable$OutputEncoding
to instruct PowerShell to send data to external programs via the pipeline in UTF-8:- Note that running
chcp 65001
from inside a PowerShell session is not effective, because .NET caches the console’s output encoding on startup and is unaware of later changes made withchcp
; additionally, as stated, Windows PowerShell requires$OutputEncoding
to be set — see this answer for details.
- Note that running
$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding
- For example, here’s a quick-and-dirty approach to add this line to
$PROFILE
programmatically:
'$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding' + [Environment]::Newline + (Get-Content -Raw $PROFILE -ErrorAction SilentlyContinue) | Set-Content -Encoding utf8 $PROFILE
-
For
cmd.exe
, define an auto-run command via the registry, in valueAutoRun
of keyHKEY_CURRENT_USERSoftwareMicrosoftCommand Processor
(current user only) orHKEY_LOCAL_MACHINESoftwareMicrosoftCommand Processor
(all users):- For instance, you can use PowerShell to create this value for you:
# Auto-execute `chcp 65001` whenever the current user opens a `cmd.exe` console
# window (including when running a batch file):
Set-ItemProperty 'HKCU:SoftwareMicrosoftCommand Processor' AutoRun 'chcp 65001 >NUL'
Optional reading: Why the Windows PowerShell ISE is a poor choice:
While the ISE does have better Unicode rendering support than the console, it is generally a poor choice:
-
First and foremost, the ISE is obsolescent: it doesn’t support PowerShell (Core) 7+, where all future development will go, and it isn’t cross-platform, unlike the new premier IDE for both PowerShell editions, Visual Studio Code, which already speaks UTF-8 by default for PowerShell Core and can be configured to do so for Windows PowerShell.
-
The ISE is generally an environment for developing scripts, not for running them in production (if you’re writing scripts (also) for others, you should assume that they’ll be run in the console); notably, with respect to running code, the ISE’s behavior is not the same as that of a regular console:
-
Poor support for running external programs, not only due to lack of supporting interactive ones (see next point), but also with respect to:
-
character encoding: the ISE mistakenly assumes that external programs use the ANSI code page by default, when in reality it is the OEM code page. E.g., by default this simple command, which tries to simply pass a string echoed from
cmd.exe
through, malfunctions (see below for a fix):
cmd /c echo hü | Write-Output
-
Inappropriate rendering of stderr output as PowerShell errors: see this answer.
-
-
The ISE dot-sources script-file invocations instead of running them in a child scope (the latter is what happens in a regular console window); that is, repeated invocations run in the very same scope. This can lead to subtle bugs, where definitions left behind by a previous run can affect subsequent ones.
-
-
As eryksun points out, the ISE doesn’t support running interactive external console programs, namely those that require user input:
The problem is that it hides the console and redirects the process output (but not input) to a pipe. Most console applications switch to full buffering when a file is a pipe. Also, interactive applications require reading from stdin, which isn’t possible from a hidden console window. (It can be unhidden via
ShowWindow
, but a separate window for input is clunky.)
-
If you’re willing to live with that limitation, switching the active code page to
65001
(UTF-8) for proper communication with external programs requires an awkward workaround:-
You must first force creation of the hidden console window by running any external program from the built-in console, e.g.,
chcp
— you’ll see a console window flash briefly. -
Only then can you set
[console]::OutputEncoding
(and$OutputEncoding
) to UTF-8, as shown above (if the hidden console hasn’t been created yet, you’ll get ahandle is invalid error
).
-
[1] In PowerShell, if you never call external programs, you needn’t worry about the system locale (active code pages): PowerShell-native commands and .NET calls always communicate via UTF-16 strings (native .NET strings) and on file I/O apply default encodings that are independent of the system locale. Similarly, because the Unicode versions of the Windows API functions are used to print to and read from the console, non-ASCII characters always print correctly (within the rendering limitations of the console).
In cmd.exe
, by contrast, the system locale matters for file I/O (with <
and >
redirections, but notably including what encoding to assume for batch-file source code), not just for communicating with external programs in-memory (such as when reading program output in a for /f
loop).
[2] In PowerShell v4-, where the static ::new()
method isn’t available, use $OutputEncoding = (New-Object System.Text.UTF8Encoding).psobject.BaseObject
. See GitHub issue #5763 for why the .psobject.BaseObject
part is needed.
Windows
- 09.06.2020
- 61 706
- 6
- 150
- 147
- 3
- Содержание статьи
- Исправляем проблему с кодировкой с помощью смены шрифта
- Исправляем проблему с кодировкой с помощью смены кодировки
- Комментарии к статье ( 6 шт )
- Добавить комментарий
В некоторых случаях, когда используется неверная кодировка, могут возникать так называемые кракозябры или иероглифы, т.е. не читаемые символы, которые невозможно разобрать при работе с командной строкой. Эти проблемы могут также возникать и при запуске различных BAT-файлов. В данной статье мы расскажем о том, как можно сменить шрифт или кодировку, чтобы избавиться от этой проблемы. Пример таких не читаемых символов можно видеть на картинке ниже:
Исправляем проблему с кодировкой с помощью смены шрифта
Первым делом нужно зайти в свойства окна: Правой кнопкой щелкнуть по верхней части окна -> Свойства -> в открывшемся окне в поле Шрифт выбрать Lucida Console и нажать кнопку ОК.
После этого не читаемые символы должны исчезнуть, а текст должен выводиться на русском языке.
Исправляем проблему с кодировкой с помощью смены кодировки
Вместо смены шрифта, можно сменить кодировку, которая используется при работе cmd.exe.
Узнать текущую кодировку можно введя в командной строке команду chcp
, после ввода данной команды необходимо нажать Enter.
Как видно на скриншоте, текущая используемая кодировка Windows-1251
Для изменения кодировки нам необходимо воспользоваться командой chcp <код_новой_кодировки>
, где <код_новой_кодировки> — это сам код кодировки, на которую мы хотим переключиться. Возможные значения:
- 1251 — Windows-кодировка (Кириллица);
- 866 — DOS-кодировка;
- 65001 — Кодировка UTF-8;
Т.е. для смены кодировки на DOS, команда примет следующий вид:
chcp 866
Для смены кодировки на UTF-8, команда примет следующий вид:
chcp 65001
Для смены кодировки на Windows-1251, команда примет следующий вид:
chcp 1251
Время чтение: 4 минуты
2014-01-19
Как корректно отобразить Русский текст в CMD. Проблемы с кодировкой могут возникнуть, например, при выполнении Bat файла, когда нужно вывести в консоль русский текст и при других обстоятельствах, о которых речь пойдёт далее.
Рассмотрим пример: когда нужно вывести в консоль Русский текст, скажем «Примет мир». Для этого создадим Bat файл с именем «1.bat». Используйте для этого обычный Блокнот Windows (Notepad.exe) Запишем в него следующие строки!
@Echo off echo. echo ПРИВЕТ МИР echo. Pause |
Для тех, кто не понял или не в курсе, строчки «echo.» я добавил специально, что бы были отступы, от строки «Примет мир»
Теперь запускаем файл 1.bat и результат будет такого вида.
Как видим проблема с кодировкой в cmd на лицо. И произошло это по следующей причине.
Стандартный блокнот Windows сохранил Bat файл в кодировке «1251» а консоль вывела его в кодировки «866». Вот от сюда все проблемы!
Решения проблемы с кодировкой в CMD. 1 Способ.
Для решения проблемы нужно просто использовать текстовой редактор, с помощью которого можно сохранить текст в кодировке «866». Для этих целей прекрасно подходит «Notepad++» (Ссылку для загрузки Вы можете найти в моём Twitter-e).
Скачиваем и устанавливаем на свой компьютер «Notepad++».
После запуска «Notepad++» запишете в документ те же строки, которые мы уже ранние записывали в стандартный блокнот.
@Echo off echo. echo ПРИВЕТ МИР echo. Pause |
Теперь осталось сохранить документ с именем «2.bat» в правильной кодировке. Для этого идём в меню «Кодировки > Кодировки > Кириллица > OEM-866»
и теперь сохраняем файл с именем «2.bat» и запускаем его! Поле запуска результат на лицо.
Как видим, текст на Русском в CMD отобразился, как положено.
Решения проблемы с кодировкой в CMD. 2 Способ.
Теперь рассмотрим ещё одну ситуацию, когда могут возникнуть проблемы с кодировкой в CMD.
Допустим, ситуация требует сохранить результат выполнения той или иной команды в обычный «TXT» файл. В приделах этого поста возьмём для примера команду «HELP».
Задача: Сохранить справку CMD в файл «HelpCMD.txt. Для этого создайте Bat файл и запишите в него следующие строки.
@Echo off Help > C:HelpCMD.txt Pause |
После выполнения Bat файла в корне диска «C:» появится файл «HelpCMD.txt» и вместо справки получится вот что:
Естественно, такой вариант не кому не понравится и что бы сохранить справку в понятном для человека виде, допишите в Bat файл строку.
Теперь содержимое кода будет такое.
@Echo off chcp 1251 >nul Help > C:HelpCMD.txt Pause |
После выполнения «Батника» результат будет такой:
Вот так на много лучше, правда?
Пожалуй, на этом я закончу пост. Добавить больше нечего. Если у Вас имеются какие-то соображения по данной теме, буду рад Вашему комментарию к посту.
Дополнительно из комментариев то Garric
Автор очень хорошо описал принцип. ! Но это неудобно.
Нужно бы добавить. Если автор добавит это в статью то это будет Good.
Создаём файл .reg следующего содержания:
——
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT.batShellNew]
«FileName»=»BATНастроенная кодировка.bat»
——
Выполняем.
——
Топаем в %SystemRoot%SHELLNEW
Создаём там файл «BATНастроенная кодировка.bat»
Открываем в Notepad++
Вводим любой текст. (нужно!) Сохраняемся.
Удаляем текст. Меняем кодировку как сказано в статье. Сохраняемся.
———-
Щёлкаем правой кнопкой мыши по Рабочему столу. Нажимаем «Создать» — «Пакетный файл Windows».
Переименовываем. Открываем в Notepad++. Пишем батник.
В дальнейшем при работе с файлом не нажимаем ничего кроме как просто «Сохранить». Никаких «Сохранить как».
Добавил(а) microsin
Иногда по неизвестным причинам некоторые команды русскоязычной версии Windows выводят русский текст в нечитаемой кодировке, кракозябрами.
Например, команда help выводит нормальный текст:
Но при этом подсказка telnet выводит в ответ кракозябры.
Так может происходить, к примеру, если текущая кодировка консоли 866, а утилита telnet.exe почему-то выводит текст в кодировке 1251. Вывести текст в нужной кодировке поможет команда chcp, которая устанавливает нужную кодировку.
Вот так можно посмотреть текущую кодировку консоли:
c:Documents and Settingsuser>chcp Текущая кодовая страница: 866 c:Documents and Settingsuser>
А вот так можно поменять кодировку на 1251, после чего вывод подсказки telnet будет отображаться нормально:
c:Documents and Settingsuser>chcp 1251 Текущая кодовая страница: 1251 c:Documents and Settingsuser>
К сожалению, заранее угадать, в какой кодировке выводится текст, невозможно, поэтому проще попробовать установить командой chcp разные кодировки, чтобы добиться правильного отображения русского текста. Обычно используются кодировки 866 (кодировка русского текста DOS), 1251 (кодировка русского текста Windows), 65001 (UTF-8).
[Шрифт cmd.exe]
Иногда кракозябры можно убрать, если выбрать в свойствах окна cmd.exe шрифт Lucida Console (по умолчанию там стоит «Точечные шрифты»).
[Ссылки]
1. Универсальный декодер — конвертер кириллицы.
Проблема: в консоли кириллические символы отображаются в неверной кодировке (в народе «кракозябры»):
При этом, если выполнить команду
chcp 866
кириллица становится читаемой только для текущего сеанса. А при перезапуске командной строки кодировка снова сбивается. Если у вас ситуация выглядит так же, то это означает, что неверные параметры кодовой страницы берутся из реестра и решать проблему нужно именно там.
Как установить правильную кодировку в консоли
Запустите редактор реестра:
Откройте раздел HKEY_CURRENT_USERConsole и проверьте значение параметра CodePage (должно быть 866).
В нашем примере на картинке мы видим, что в параметре по какой-то причине указана кодировка 1251, что бесспорно и является причиной появления абракадабры.
Если у вас значение этого параметра отличается от 866, нажмите два раза по параметру CodePage:
Установите переключатель в положение Десятичная.
В поле Значение введите 866.
Нажмите OK:
Перезапустите командную строку (закройте окно и запустите его заново — Win+R, cmd, enter). Вы должны увидеть корректное отображение кириллицы:
Обновлено 14.02.2020
Добрый день! Уважаемые читатели и гости одного из крупнейших IT блогов по системному администрированию Pyatilistnik.org. В прошлый раз я вам подробно рассказывал, как диагностировать вашу систему, когда у вас нет интернета, судя по комментариям данный материал оказался полезным. Не так давно один из моих приятелей задал мне вопрос, почему при сохранении текстового файла с выводом результатов из командной стоки Windows у него вместо русского языка, отображается какая-то кракозябра. Давайте я покажу, как выкручиваться из данной ситуации.
Описание проблемы
Мой приятель делал диагностику репликации Active Directory и так как полученная диагностическая информация была объемной, он логично попытался сохранить ее в текстовый файл. Напоминаю делается, это вот по такой конструкции:
repadmin /replsummary > c:tempreplsummary.log
Тут > c:tempreplsummary.log и есть функция вывода в файл.
При открытии файла он увидел вот такую абракадабры вместо русского текста:
‚аҐ¬п § ЇгбЄ бў®¤ЄЁ Ї® ९«ЁЄ жЁЁ: 2020-02-14 18:10:03
Ќ з в бЎ®а ¤ ле ¤«п бў®¤ЄЁ Ї® ९«ЁЄ жЁЁ, Ї®¤®¦¤ЁвҐ:
…….
€бе®¤л© DSA ЁЎ. ¤Ґ«мв бЎ®Ґў/ўбҐЈ® %% ®иЁЎЄ
Согласитесь, что это не очень красиво и читаемо.
Варианты устранения краскозябр в файле после экспорта из cmd
Первый вариант, это использование оболочки PowerShell. PowerShell умеет запускать большую часть утилит, к которым вы привыкли в командной строке, у него для этого есть алиасы в виде командлетов. Самое классное, что в отличии от cmd он сохраняет данные в нормальном виде, даже если они по русски. Для примера я выполню в PowerShell предыдущую команду;
repadmin /replsummary > c:tempreplsummary.log
В результате вы сразу можете оценить его преимущество и еще раз задуматься, чтобы использовать его.
Так же вы можете использовать командлет PowerShell под названием Out-File, он позволяет производить вывод полученных данных в виде файла, единственное не забываем указать нужное место, так же если места нет, вы его можете создать с помощью ключа -Force.
repadmin /replsummary | Out-File c:tempreplsummary.log
Если же вы хотите использовать именно командную строку, то вам необходимо перед вашей командой или в скрипте в самом начале выполнить вот эти строки:
@echo off
chcp 855 (По умолчанию в командной строке стоит — 866 или 1251)
В результате чего на выходе я получил положительный результат и никакой абракадабры вместо русского текста я не увидел.
Вот пример бат файла, где я использовал кодировку chcp 855.
Убираем кракозябры через реестр
В реестре Windows есть ветка «HKEY_CURRENT_USERConsole%SystemRoot%_system32_cmd.exe», где вы можете создать ключ CodePage со значением 855. Напоминаю, что из себя представляют эти трехзначные цифры, обратите внимание, что 855 это именно кириллица (Дополнительно можно почитать https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers).
В командной строке от имени администратора выполните команду по добавлению ключа:
REG ADD HKCUConsole%SystemRoot^%_system32_cmd.exe /v CodePage /t REG_DWORD /d 855
Выглядеть это будет вот так
Так же создать ключ реестра можно и через PowerShell, вот такими командами:
New-Item -ErrorAction Ignore HKCU:Console%SystemRoot%_system32_cmd.exe
Set-ItemProperty HKCU:Console%SystemRoot%_system32_cmd.exe CodePage 855
Надеюсь, что у вас теперь все будет в читаемом виде. На этом у меня все, с вами был Иван Семин, автор и создатель IT портала Pyatilistnik.org.