Введение
Консольные приложения до сих пор остаются наиболее востребованным видом приложений, большинство разработчиков оттачивают архитектуру и бизнес-логику именно в консоли. При этом они нередко сталкиваются с проблемой локализации – русский текст, который вполне адекватно отражается в исходном файле, при выводе на консоль приобретает вид т.н. “кракозябр”.
В целом, локализация консоли Windows при наличии соответствующего языкового пакета не представляется сложной. Тем не менее, полное и однозначное решение этой проблемы, в сущности, до сих пор не найдено. Причина этого, главным образом, кроется в самой природе консоли, которая, являясь компонентом системы, реализованным статическим классом System.
Console, предоставляет свои методы приложению через системные программы-оболочки, такие как командная строка или командный процессор (cmd.exe), PowerShell, Terminal и другие. По сути, консоль находится под двойным управлением – приложения и оболочки, что является потенциально конфликтной ситуацией, в первую очередь в части использования кодировок.
Данный материал не предлагает строгий алгоритм действий, а направлен на описание узловых проблем, с которыми неизбежно сталкивается разработчик локализованного консольного приложения, а также некоторые возможные пути их разрешения. Предполагается, что это позволит разработчику сформировать стратегию работы с локализованной консолью и эффективно реализовать существующие технические возможности, большая часть которых хорошо описана и здесь опущена.
Command-line – сменить клавиатуру на английский язык в командной строке с кириллицы
В русской клавиатуре, вероятно, есть ключ-модификатор для латинского текста.
Некоторые вероятные подозреваемые – это ключ Caps Lock (латинская блокировка), клавиша Alt Alt (AltGr) или, возможно, комбинация клавиш Alt и Сдвиньте вместе.
Если бы вы могли посмотреть файл раскладки (или запустить dumpkeys), то вы точно знаете. Но может быть трудно найти информацию, пока ваша клавиатура застряла в незнакомом каркасе!
Комментарий в верхней части /usr/share/keymaps/i386/qwerty/ru.kmap.gz в Ubuntu 16.04 LTS (Xenial Xerus) говорит:
«Кириллический» режим переключается клавишей Right_Ctrl и сдвигается клавишей AltGr.
Надеюсь, ваша клавиатура имеет правый ключ Caps Lock ! Если это не так, вам нужно будет удерживать клавишу Alt-Alt (AltGr) во время переключения.
Вам понадобится
- Программное обеспечение:
- – командная строка;
- – терминал.
Виды консолей
В общем случае функции консоли таковы:
управление операционной системой и системным окружением приложений на основе применения стандартных системных устройств ввода-вывода (экран и клавиатура), использования команд операционной системы и/или собственно консоли;
запуск приложений и обеспечение их доступа к стандартным потокам ввода-вывода системы, также с помощью стандартных системных устройств ввода-вывода.
Основная консоль Windows – командная строка или иначе командный процессор (CMD). Большие возможности предоставляют оболочки PowerShell (PS), Windows PowerShell (WPS) и Terminal.
По умолчанию Windows устанавливает Windows Power Shell мажорной версией до 5, однако предлагает перейти на новую версию – 7-ку, имеющую принципиальное отличие (вероятно, начинающееся с 6-ки) – кроссплатформенность. Terminal – также отдельно уставливаемое приложение, по сути интегратор всех ранее установленных оболочек PowerShell и командной строки.
Отдельным видом консоли можно считать консоль отладки Visual Studio (CMD-D).
Инструкция
По умолчанию для каждой такой утилиты используются стандартные сочетания клавиш переключения раскладки клавиатуры, т.к. специальных горячих клавиш не предусмотрено.
Конфликт кодировок
Полностью локализованная консоль в идеале должна поддерживать все мыслимые и немыслимые кодировки приложений, включая свои собственные команды и команды Windows, меняя “на лету” кодовые страницы потоков ввода и вывода. Задача нетривиальная, а иногда и невозможная – кодовые страницы DOS (CP437, CP866) плохо совмещаются с кодовыми страницами Windows и Unicode.
Локализация отладочной консоли visual studio
Отладочная консоль – наиболее востребованная консоль разработчика, гораздо более удобная, чем внешняя консоль, поэтому резонно приложить максимум усилий для ее локализации.
На самом деле, правильнее говорить о локализации приложения в консоли – это важное уточнение. Microsoft по этому поводу высказывается недвусмысленно: “Programs that you start after you assign a new code page use the new code page. However, programs (except Cmd.exe) that you started before assigning the new code page will continue to use the original code page”.
Иными словами, консоль можно локализовать когда угодно и как угодно, но приложение будет локализовано в момент стабилизации взаимодействия с консолью в соответствии с текущей локализацией консоли, и эта локализация сохранится до завершения работы приложения. В связи с этим возникает вопрос – в какой момент окончательно устанавливается связь консоли и приложения?
Важно! Приложение окончательно стабилизирует взаимодействие с консолью в момент начала ввода-вывода в консоль, благодаря чему и появляется возможность программного управления локализацией приложения в консоли – до первого оператора ввода-вывода.
Ниже приведен пример вывода тестового приложения в консоль, иллюстрирующий изложенное. Метод Write получает номера текущих страниц, устанавливает новые кодовые страницы вводного и выводного потоков, выполняет чтение с консоли и записывает выводную строку, содержащий русский текст, в том числе считанный с консоли, обратно в консоль. Операция повторяется несколько раз для всех основных кодовых страниц, упомянутых ранее.
F:LoggingConsole.TestbinReleasenet5.0>chcp
Active code page: 1251
F:LoggingConsole.TestbinReleasenet5.0>loggingconsole.test
Codepages: current 1251:1251, setted 437:437, ΓΓεΣΦ∞ 5 ±Φ∞ΓεδεΓ ∩ε-≡≤±±ΩΦ: Θ÷≤Ωσ=Θ÷≤Ωσ
Codepages: current 437:437, setted 65001:65001, 5 -: =
Codepages: current 65001:65001, setted 1252:1252, ââîäèì 5 ñèìâîëîâ ïî-ðóññêè: éöóêå=éöóêå
Codepages: current 1252:1252, setted 1251:1251, вводим 5 символов по-русски: йцуке=йцуке
Codepages: current 1251:1251, setted 866:866, ттюфшь 5 ёшьтюыют яю-Ёєёёъш: щЎєъх=щЎєъх
Codepages: current 866:866, setted 1251:1251, вводим 5 символов по-русски: йцуке=йцуке
Codepages: current 1251:1251, setted 1252:1252, ââîäèì 5 ñèìâîëîâ ïî-ðóññêè: éöóêå=éöóêå
F:LoggingConsole.TestbinReleasenet5.0>chcp
Active code page: 1252
приложение запущено в консоли с кодовыми страницами 1251 (строка 2);
приложение меняет кодовые страницы консоли (current, setted);
приложение остановлено в консоли с кодовыми страницами 1252 (строка 11, setted);
по окончании работы приложения изменения консоли сохраняются (строка 14 – Active codepage 1252);
Приложение адекватно локализовано только в случае совпадения текущих кодовых страниц консоли (setted 1251:1251) с начальными кодовыми страницами (строки 8 и 10).
Код тестового приложения под катом
Программное управление кодировками консоли – это единственный способ гарантированной адекватной локализацией приложения в консоли. Языки .Net такой возможности не предоставляют, однако предоставляют функции WinAPI: SetConsoleCP(uint numcp) и SetConsoleOutputCP(uint numcp), где numcp – номер кодовой страницы потоков ввода и вывода соответственно.
Совет 7. Обязательный и повторный! Функции SetConsoleCP должны размещаться в коде до первого оператора ввода-вывода в консоль.
Проблемы консолей visual studio
В Visual Studio имеется возможность подключения консолей, по умолчанию подключены командная строка для разработчика и Windows PowerShell для разработчика. К достоинствам можно отнести возможности определения собственных параметров консоли, отдельных от общесистемных, а также запуск консоли непосредственно в директории разработки.
Отдельной опцией Visual Studio является встроенная односеансная консоль отладки, которая перехватывает команду Visual Studio на запуск приложения, запускается сама, ожидает компиляцию приложения, запускает его и отдает ему управление. Таким образом, отладочная консоль в течение всего рабочего сеанса находится под управлением приложения и возможность использования команд Windows или самой консоли, включая команду CHCP, не предусмотрена.
Совет 6. Тестирование приложения целесообразно выполнять во внешних консолях, более дружелюбных к локализации.
Анализ проблем консолей был бы не полон без ответа на вопрос – можно ли запустить консольное приложение без консоли? Можно – любой файл “.exe” запустится двойным кликом, и даже откроется окно приложения. Однако консольное приложение, по крайней мере однопоточное, по двойному клику запустится, но консольный режим не поддержит – все консольные вводы-выводы будут проигнорированы, и приложение завершится
Стратегия локализации приложения в консоли
Удалить приложение PowerShell (если установлено), сохранив Windows PowerShell;
Установить в качестве кодовую страницу консоли по умолчанию CP65001 (utf-8 Unicode) или CP1251 (Windows-1251-Cyr), см. совет 5;
Разработку приложений выполнять в кодировке utf-8 Unicode;
Контролировать кодировку файлов исходных кодов, текстовых файлов данных, например с помощью Notepad ;
Реализовать программное управление локализацией приложения в консоли, пример ниже под катом: