Как использовать символы Юникода в командной строке Windows?

У нас есть проект в Team Foundation Server (TFS), в котором есть не английский символ (š). При попытке написать несколько вещей, связанных со сборкой, мы столкнулись с проблемой - мы не можем передать букву š инструментам командной строки. Командная строка или что-то еще портит ее, и утилита tf.exe не может найти указанный проект.

Я пробовал разные форматы для файла.bat (ANSI, UTF-8 с BOM и без BOM), а также создавал сценарии в JavaScript (что по сути является Unicode) - но не повезло. Как мне выполнить программу и передать ей командную строку Unicode?

20 ответов

Решение

Мой опыт: я использую ввод / вывод Unicode в консоли в течение многих лет (и делаю это много раз в день. Более того, я разрабатываю инструменты поддержки именно для этой задачи). Существует очень мало проблем, насколько вы понимаете следующие факты / ограничения:

  • CMD и "консоль" являются несвязанными факторами. CMD.exe это просто одна из программ, которые готовы "работать внутри" консоли ("консольные приложения").
  • НАСКОЛЬКО МНЕ ИЗВЕСТНО, CMD имеет отличную поддержку Unicode; Вы можете вводить / выводить все символы Unicode, когда активна любая кодовая страница.
  • Консоль Windows имеет МНОГО поддержки Unicode - но она не идеальна (просто "достаточно хороша"; см. Ниже).
  • chcp 65001 это очень опасно. Если программа не была специально разработана для обхода дефектов в API Windows (или не использует библиотеку времени выполнения C, которая имеет эти обходные пути), она не будет работать надежно. Win8 исправляет ½ этих проблем с cp65001 , но остальное все еще применимо к Win10.
  • я работаю в cp1252, Как я уже сказал: для ввода / вывода Unicode в консоли не нужно устанавливать кодовую страницу.

Детали

  • Для чтения / записи Unicode на консоль приложение (или его библиотека времени выполнения C) должно быть достаточно умным, чтобы не File-I/O API, но Console-I/O API. (Например, посмотрите, как это делает Python.)
  • Аналогично, чтобы читать аргументы командной строки Unicode, приложение (или его библиотека времени выполнения C) должно быть достаточно умным, чтобы использовать соответствующий API.
  • Консоль рендеринга шрифтов поддерживает только символы Юникода в BMP (другими словами: ниже U+10000). Поддерживается только простая отрисовка текста (поэтому европейские и некоторые восточноазиатские языки должны нормально работать, если используются предварительно составленные формы). [Здесь есть мелкий мелкий шрифт для восточной азии и для символов U+0000, U+0001, U+30FB.]

Практические соображения

  • Значения по умолчанию для Window не очень полезны. Для лучшего опыта нужно настроить 3 части конфигурации:

    • Для вывода: полный консольный шрифт. Для достижения наилучших результатов я рекомендую мои сборки. (Инструкции по установке присутствуют там - и также перечислены в других ответах на этой странице.)
    • Для ввода: способная раскладка клавиатуры. Для достижения наилучших результатов я рекомендую мои макеты.
    • Для ввода: разрешить шестнадцатеричный ввод Unicode.
  • Еще одна ошибка с "Вставкой" в консольное приложение (очень техническое):

    • Ввод шестнадцатеричного символа обеспечивает KeyUp из Alt; все остальные способы доставки персонажа происходят на KeyDown; так много приложений не готовы увидеть персонажа на KeyUp, (Применимо только к приложениям, использующим Console-I/O API).
    • Вывод: многие приложения не будут реагировать на входные события HEX.
    • Более того, то, что происходит с "вставленным" символом, зависит от текущей раскладки клавиатуры: если символ можно набирать без использования префиксных клавиш (но с произвольной сложной комбинацией модификаторов, как в Ctrl-Alt-AltGr-Kana-Shift-Gray*) затем он доставляется по нажатию эмулируемой клавиши. Это то, что ожидает любое приложение - так что вставка чего-либо, содержащего только такие символы - это хорошо.
    • Однако "другие" символы доставляются путем эмуляции ввода HEX.

    Вывод: если раскладка клавиатуры не поддерживает ввод МНОГО символов без префиксных клавиш, некоторые ошибочные приложения могут пропускать символы, когда вы Paste через пользовательский интерфейс консоли: Alt-Space E P, (Вот почему я рекомендую использовать раскладки клавиатуры!)

Следует также иметь в виду, что "альтернативные," более способные "консоли" для Windows вовсе не являются консолями. Они не поддерживают Console-I/O API, поэтому программы, которые работают с этими API, не будут работать. (Программы, которые используют только "API-интерфейсы File-I/O для файловых дескрипторов консоли", будут работать нормально).

Одним из примеров такого неконсольного является частью MicroSoft Powershell, Я не использую это; экспериментировать, нажмите и отпустите WinKey затем введите powershell,


(С другой стороны, есть такие программы, как ConEmu или же ANSICON которые пытаются сделать больше: они "пытаются" перехватить Console-I/O API для работы "настоящих консольных приложений" тоже. Это определенно работает для игрушечных примеров программ; в реальной жизни это может или не может решить ваши конкретные проблемы. Эксперимент.)

Резюме

  • установить шрифт, раскладку клавиатуры (и при желании разрешить ввод в шестнадцатеричном формате).

  • используйте только программы, которые проходят Console-I/O API и принимают аргументы командной строки Unicode. Например, любой cygwin Скомпилированная программа должна быть в порядке. Как я уже сказал, CMD тоже хорошо.

UPD: Изначально за ошибку в cp65001 Я смешивал слои ядра и CRTL (UPD²: и API пользовательского режима Windows!). Также: Win8 исправляет половину этой ошибки; Я разъяснил раздел о "лучшей консоли" и добавил ссылку на то, как это делает Python.

Пытаться:

chcp 65001

который изменит кодовую страницу на UTF-8. Также вам необходимо использовать консольные шрифты Lucida.

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

Решение, которое работает для меня:

В командном файле измените страницу кодировки

Мой пакетный файл:

chcp 1250
copy "O:\VEŘEJNÉ\ŽŽŽŽŽŽ\Ž.xls" c:\temp

Пакетный файл должен быть сохранен в CP 1250.

Обратите внимание, что консоль не будет правильно отображать символы, но будет понимать их...

Проверьте язык для не-Unicode программ. Если у вас проблемы с русским языком в консоли Windows, вам следует установить русский язык здесь:

Изменение языка для программ, не поддерживающих Юникод

Изменить кодовую страницу по умолчанию консоли Windows довольно сложно. При поиске в Интернете вы обнаружите различные предложения, однако некоторые из них могут полностью сломать Windows, т. Е. Ваш компьютер больше не загружается.

Наиболее безопасное решение это: перейдите в раздел реестра HKEY_CURRENT_USER\Software\Microsoft\Command Processor и добавить строковое значение Autorun знак равно chcp 65001,

Или вы можете использовать этот небольшой пакетный скрипт для наиболее распространенных кодовых страниц.

@ECHO off

SET ROOT_KEY="HKEY_CURRENT_USER"


FOR /f "skip=2 tokens=3" %%i in ('reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage /v OEMCP') do set OEMCP=%%i

ECHO System default values:

ECHO.
ECHO ...............................................
ECHO Select Codepage 
ECHO ...............................................
ECHO.
ECHO 1 - CP1252
ECHO 2 - UTF-8
ECHO 3 - CP850
ECHO 4 - ISO-8859-1
ECHO 5 - ISO-8859-15
ECHO 6 - US-ASCII
ECHO.
ECHO 9 - Reset to System Default (CP%OEMCP%)
ECHO 0 - EXIT
ECHO.


SET /P  CP="Select a Codepage: "

if %CP%==1 (
    echo Set default Codepage to CP1252
    reg add "%ROOT_KEY%\Software\Microsoft\Command Processor" /v Autorun /t REG_SZ /d "@chcp 1252>nul" /f
) else if %CP%==2 (
    echo Set default Codepage to UTF-8
    reg add "%ROOT_KEY%\Software\Microsoft\Command Processor" /v Autorun /t REG_SZ /d "@chcp 65001>nul" /f
) else if %CP%==3 (
    echo Set default Codepage to CP850
    reg add "%ROOT_KEY%\Software\Microsoft\Command Processor" /v Autorun /t REG_SZ /d "@chcp 850>nul" /f
) else if %CP%==4 (
    echo Set default Codepage to ISO-8859-1
    add "%ROOT_KEY%\Software\Microsoft\Command Processor" /v Autorun /t REG_SZ /d "@chcp 28591>nul" /f
) else if %CP%==5 (
    echo Set default Codepage to ISO-8859-15
    add "%ROOT_KEY%\Software\Microsoft\Command Processor" /v Autorun /t REG_SZ /d "@chcp 28605>nul" /f
) else if %CP%==6 (
    echo Set default Codepage to ASCII
    add "%ROOT_KEY%\Software\Microsoft\Command Processor" /v Autorun /t REG_SZ /d "@chcp 20127>nul" /f
) else if %CP%==9 (
    echo Reset Codepage to System Default
    reg delete "%ROOT_KEY%\Software\Microsoft\Command Processor" /v AutoRun /f
) else if %CP%==0 (
    echo Bye
) else (
    echo Invalid choice
    pause
)

С помощью @chcp 65001>nul вместо chcp 65001 подавляет вывод "Активная кодовая страница: 65001", который вы будете получать каждый раз, когда запускаете новые окна командной строки.

Полный список всех доступных номеров вы можете получить из идентификаторов кодовых страниц

Обратите внимание, что настройки будут применяться только для текущего пользователя. Если вы хотите установить его для всех пользователей, замените строку SET ROOT_KEY="HKEY_CURRENT_USER" от SET ROOT_KEY="HKEY_LOCAL_MACHINE"

На компьютере с Windows 10 x64 я заставил командную строку отображать не английские символы:

Откройте командную строку с повышенными правами (запустите CMD.EXE от имени администратора). Запросите в реестре доступные шрифты TrueType для консоли:

    REG query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont"

Вы увидите вывод вроде:

    0    REG_SZ    Lucida Console
    00    REG_SZ    Consolas
    936    REG_SZ    *新宋体
    932    REG_SZ    *MS ゴシック

Теперь нам нужно добавить шрифт TrueType, который поддерживает такие символы, как Courier New. Мы делаем это, добавляя нули к имени строки, поэтому в этом случае следующим будет "000":

    REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont" /v 000 /t REG_SZ /d "Courier New"

Теперь мы реализуем поддержку UTF-8:

    REG ADD HKCU\Console /v CodePage /t REG_DWORD /d 65001 /f

Установить шрифт по умолчанию "Новый курьер":

    REG ADD HKCU\Console /v FaceName /t REG_SZ /d "Courier New" /f

Установите размер шрифта 20:

    REG ADD HKCU\Console /v FontSize /t REG_DWORD /d 20 /f

Включите быстрое редактирование, если вам нравится:

    REG ADD HKCU\Console /v QuickEdit /t REG_DWORD /d 1 /f

Фактически, дело в том, что командная строка на самом деле понимает эти неанглийские символы, просто не может отображать их правильно.

Когда я ввожу путь в командной строке, который содержит некоторые неанглийские символы, он отображается как "?????????????". Когда вы отправляете свою команду (в моем случае cd "??????????????"), все работает как положено.

Один действительно простой вариант - установить оболочку Windows bash, такую ​​как MinGW, и использовать ее:

Существует некоторая кривая обучения, поскольку вам нужно будет использовать функциональность командной строки Unix, но вам понравится ее мощь, и вы можете установить консольный символ UTF-8.

Конечно, вы также получаете все обычные *nix лакомства, такие как grep, find, less и т. Д.

Я нашел этот метод полезным в новых версиях Windows 10:

Включите эту функцию: "Бета-версия: используйте Unicode UTF-8 для всемирной языковой поддержки"

Панель управления -> Региональные настройки -> Административная вкладка-> Изменить язык системы...

Начиная с июня 2019 года, с Windows 10 вам не придется менять кодовую страницу.

См. " Знакомство с терминалом Windows" (от Кайлы Синнамон) и Microsoft / Терминал.
Благодаря использованию шрифта Consolas будет обеспечена частичная поддержка Unicode.

Как указано в Microsoft/Terminal выпуск 387:

В настоящее время в Юникоде насчитывается 87 887 иероглифов. Тебе они тоже нужны?
Нам нужна граница, и символы за этой границей должны обрабатываться резервным шрифтом / связыванием шрифта / чем угодно.

Что Консолас должен покрыть:

  • Символы, используемые в качестве символов, которые используются современными программами OSS в CLI.
  • Эти персонажи должны соответствовать дизайну и метрикам Консоласа, и должны быть правильно выровнены с существующими персонажами Консоласа

Что Консолас НЕ должен покрывать:

  • Символы и знаки препинания, которые помимо латинского, греческого и кириллического, особенно символов, нуждаются в сложном формировании (например, арабском).
  • Эти символы должны обрабатываться с резервным шрифтом.

Поскольку я не видел полных ответов по Python 2.7, я опишу два важных шага и дополнительный шаг, который весьма полезен.

  1. Вам нужен шрифт с поддержкой Unicode. Windows поставляется с Lucida Console, которую можно выбрать, щелкнув правой кнопкой мыши строку заголовка командной строки и выбрав Defaults вариант. Это также дает доступ к цветам. Обратите внимание, что вы также можете изменить настройки для командных окон, вызываемых определенными способами (например, открыть здесь, Visual Studio), выбрав Properties вместо.
  2. Вам нужно установить кодовую страницу cp65001Это, похоже, попытка Microsoft предложить поддержку UTF-7 и UTF-8 для командной строки. Сделай это, запустив chcp 65001в командной строке. После установки он остается таким до тех пор, пока окно не закроется. Вам нужно будет повторять это каждый раз, когда вы запускаете cmd.exe.

Для более постоянного решения, обратитесь к этому ответу на Супер пользователя. Короче говоря, создать REG_SZ (Строка) запись с использованием regedit на HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor и назовите это AutoRun, Измените значение на chcp 65001, Если вы не хотите видеть выходное сообщение из команды, используйте @chcp 65001>nul вместо.

Некоторые программы испытывают трудности при взаимодействии с этой кодировкой, при этом MinGW является заметной ошибкой при компиляции с бессмысленным сообщением об ошибке. Тем не менее, это работает очень хорошо и не вызывает ошибок в большинстве программ.

Эта проблема довольно раздражает. У меня обычно есть китайские иероглифы в имени файла и содержимом файла. Обратите внимание, что я использую Windows 10, вот мое решение:

Для отображения имени файла, например dir или же ls если вы установили Ubuntu Bash на Windows 10

  1. Установите регион для поддержки не-UTF 8 символов.

  2. После этого шрифт консоли изменится на шрифт этой локали, а также изменит кодировку консоли.

После того, как вы сделали предыдущие шаги, чтобы отобразить содержимое файла UTF-8, используя инструмент командной строки

  1. Измените страницу на utf-8 chcp 65001
  2. Перейдите на шрифт, который поддерживает utf-8, например Lucida Console
  3. использование type команда для просмотра содержимого файла, или cat если вы установили Ubuntu Bash на Windows 10
  4. Обратите внимание, что после установки кодировки консоли на utf-8 я не могу вводить китайский символ в cmd, используя китайский метод ввода.

Самое ленивое решение: просто используйте консольный эмулятор, такой как http://cmder.net/

Для аналогичной проблемы, (моя проблема состояла в том, чтобы показать символы UTF-8 из MySQL в командной строке),

Я решил это так:

  1. Я изменил шрифт командной строки на Lucida Console. (Этот шаг не имеет отношения к вашей ситуации. Он связан только с тем, что вы видите на экране, а не с тем, что на самом деле является персонажем).

  2. Я изменил кодовую страницу на Windows-1253. Вы делаете это в командной строке с помощью "chcp 1253". Это сработало для моего случая, когда я хотел увидеть UTF-8.

Быстрое решение для файлов.bat, если ваш компьютер отображает правильный путь / имя файла при вводе его в DOS-окне:

  1. скопируйте con temp.txt [нажмите Enter]
  2. Введите путь / имя файла [нажмите Enter]
  3. Нажмите Ctrl-Z [нажмите Enter]

Таким образом, вы создаете файл.txt - temp.txt. Откройте его в Блокноте, скопируйте текст (не волнуйтесь, он будет выглядеть нечитаемым) и вставьте его в ваш.bat файл. Выполнение созданного таким образом.bat в DOS-окне сработало для меня (кириллица, болгарский).

Я вижу несколько ответов здесь, но они, похоже, не отвечают на этот вопрос - пользователь хочет получить Unicode-ввод из командной строки.

Windows использует UTF-16 для кодирования двухбайтовых строк, поэтому вам необходимо получить их из ОС в вашей программе. Есть два способа сделать это -

1) Microsoft имеет расширение, которое позволяет main принимать массив широких символов: int wmain (int argc, wchar_t * argv []); https://msdn.microsoft.com/en-us/library/6wd819wh.aspx

2) Вызвать API Windows, чтобы получить версию командной строки в Unicode. Wchar_t win_argv = (wchar_t) CommandLineToArgvW (GetCommandLineW (), & nargs); https://docs.microsoft.com/en-us/windows/desktop/api/shellapi/nf-shellapi-commandlinetoargvw

Прочтите это: http://utf8everywhere.org/ для подробной информации, особенно если вы поддерживаете другие операционные системы.

Лучшее, что можно сделать: просто установите доступный бесплатный пакет Microsoft для японского языка. (Другие восточные языковые пакеты также будут работать, но я проверил японский.)

Это дает вам шрифты с большими наборами глифов, делает их поведением по умолчанию, изменяет различные инструменты Windows, такие как cmd, WordPad и т. Д.

Я обошел аналогичную проблему удаления файлов с именами в Юникоде, ссылаясь на них в командном файле по их коротким (8 точкам 3) именам.

Короткие имена можно посмотреть, выполнив dir /x, Очевидно, это работает только с именами файлов Unicode, которые уже известны.

Изменение кодовой страницы на 1252 работает для меня. Проблема для меня заключается в том, что символ двойного доллара - это преобразование DOS в Windows Server 2008 в другой символ.

Я использовал CHCP 1252 и колпачок перед ним в своем заявлении BCP ^§.

Имейте в виду, что для тех, кто использует WSL и не хочет дополнительных пакетов от Cygwin или Git, доступен wsltty , который предоставляет только терминал с поддержкой UTF-8.

Для utf-8: chcp 65001

Вернуться к умолчанию: chcp 437

Другие вопросы по тегам