Настройка локали в cmd windows

Обновлено: 02.07.2024

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

Работа с локалями в PHP

Работа с локалями в PHP выглядит одинаково и в UNIX, и в Windows, и в любой другой платформе. Для установки значений локали служит всего одна функция setlocale() . Чтобы выставить локаль, нужно передать функции первым аргументом категорию, на которую эта локаль распространяется, последующими список возможных локалей. Результатом будет название первой подходящей локали, которая и была установлена.

Локали в Windows

Для того, чтобы узнать, какие локали доступны в Windows, нужно зайти в панель управления, "Язык и региональные стандарты".

На вкладке "Дополнительно", в разделе "Кодовые страницы таблиц преобразования" показан список всех возможных локалей для Windows, которые можно использовать в PHP.

Кодовые страницы, которые отмечены в списке, из PHP могут быть использованы по их номеру.

В общем случае, использование выглядит по следующей схеме: Язык_Регион.Номер_кодовой_страницы

Для Украины - Ukrainian_Ukraine.1251 (cp1251).

Вместо длинных названий можно использовать сокращённые russian , american , ukrainian и так далее. При этом кодовая страница выставится с учётом региональных настроек, для России и Украины - 1251, для Америки - 1252.

Пока это можно списать на внутренний механизм PHP работы со строками. С шестой версии PHP вся обработка строк должна будет вестись в UTF-8, но до тех пор надо просто знать об этом и делать поправку.

Локали в UNIX

Выше я описал работу с локалями в Windows, теперь можно заострить внимание на UNIX-like системах. Для простоты, я буду их называть UNIX, а подразумевать FreeBSD :). В контексте данной статьи это не особо важно.

Итак, дистрибутивы UNIX поставляются в одном виде для всех, и работа рассчитана на многопользовательский режим, поэтому о правильной настройке локали должен заботиться сам пользователь, например:

Так может выглядеть работа системной команды locale , которая выводит текущие настройки локали для пользователя. А так, обычно, выглядят настройки локали для пользователя, под которым работает PHP:

Функция ucwords() должна была сделать заглавными первые буквы всех слов. А перед этим strtolower() должна была предварительно все заглавные буквы сделать строчными. Но ничего не произошло. Так же не будет работать следующий код:

Здесь первый аргумент - это категория, на которую будет распространяться локаль (константа LC_*), второй - название локали. Начиная с версии 4.3.0 можно указывать несколько имён локалей в виде массива или в качестве дополнительных аргументов. После вызова функция установит первую подходящую локаль и вернёт её имя:

С помощью команды grep я отобрал локали, которые поддерживают русский язык. Любую из них можно использовать, однако следует понимать, что данные должны быть в кодировке, на которую рассчитана локаль. Если же это правило не будет соблюдено, то результат может оказаться весьма неожиданным:

После установки правильной локали все примеры, которые не работали выше, будут работать как нужно!

По-русски заговорит и функция strftime(), которая корректно работает с локалями, а также и всё остальное, что зависит от локали.

Кодировки в MySQL

Напомню, что возможность задавать кодировки появилась только в MySQL 4.1.11 и выше.

В отличие от php, проблемы с кодировками базы данных проявляют себя гораздо быстрее, чем проблемы с локалью. И связано это прежде всего с хранением и выборкой данных, поскольку от этого зависит информация на сайте. Я не буду подробно расписывать все тонкости, поскольку есть отдельная статья, остановлюсь на самых важных моментах.

Первое, чему необходимо научиться, смотреть текущие настройки соединения с mysql:

Критичными для пользователя являются character_set_client и character_set_results, которые отвечают за кодировку, в которой данные поступают в базу, и кодировку, в которой данные поступают из базы к пользователю. Если эти две кодировки отличаются от той, в которой работает клиент, в нашем случае php-скрипты, то неминуемо будут "странности", например, при сортировке выборки или внесении данных в базу.

Второе, что необходимо знать, как правильно сообщить mysql о кодировках. Самый простой и правильный способ, это использовать запрос set names:

После этого три переменные character_set_client, character_set_connection и character_set_results примут значение cp1251. Это будет означать - клиент работает в кодировке windows-1251 (cp1251).

Помимо этого можно устанавливать непосредственно серверные переменные:

Теперь данные поступают и извлекаются в разных кодировках.

Список доступных кодировок можно просмотреть так:

И третье, что необходимо знать, - правила создания таблиц для хранения данных в нужной кодировке. К слову, данные можно хранить в любой кодировке, а работать с ними в кодировке клиента. Однако, важно понимать, что кодировки носят национальный характер и должны соответствовать вносимым данным. Иначе будут потери. Для русского языка есть три национальных кодировки koi8r, cp866, cp1251, которые могут конвертироваться друг в друга без потерь. Также можно использовать интернациональную кодировку UTF8.

Кодировку можно выставить на базу данных, таблицу и поле таблицы. Так, например, можно создать базу данных в кодировке koi8r:

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

Следующим шагом я создам таблицу в cp1251 и одним полем в utf8:

После того, как таблица создана с нужными параметрами кодировки, mysql автоматически начинает переводить данные при внесении и выборке.

Данные хранятся в разном виде, но поступают к пользователю именно так, как надо!

Кодировка HTML-страниц

Объявить кодировку html-страницы можно двумя способами: через заголовки и мета-тег в самой странице. Мета-тег используется только в статичных страницах.

Но браузер отобразит страницу корректно только в том случае, когда php-файлы сами были созданы в кодировке cp1251. Также нужно понимать, что заголовки должны быть отправлены до любого вывода на экран.

При необходимости перекодировать страницы "на лету", достаточно воспользоваться буферизацией и iconv:

Надпись "Привет, мир!" будет выведена в юникоде, при этом браузер получит информацию о кодировке через заголовки и правильно отобразит страницу. Но важно понимать, что внутри скрипта и при соединении с базой данных надо использовать windows-1251 (cp1251), поскольку страница должна быть сформирована в одной кодировке.

Важно помнить, что функции iconv доступны не всегда, и проверка на доступность этих функций не будет лишней.

Заключение

Для безопасной разработки русскоязычных веб-проектов необходимо включать в файл с общими настройками следующие команды:

Как ни странно, но эти три строчки кода значительно повышают портируемость веб-проектов.

© 2021 Антон Прибора. При копировании материалов с сайта, пожалуйста, указывайте ссылку на источник.

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

В целом, локализация консоли Windows при наличии соответствующего языкового пакета не представляется сложной. Тем не менее, полное и однозначное решение этой проблемы, в сущности, до сих пор не найдено. Причина этого, главным образом, кроется в самой природе консоли, которая, являясь компонентом системы, реализованным статическим классом System.Console, предоставляет свои методы приложению через системные программы-оболочки, такие как командная строка или командный процессор (cmd.exe), PowerShell, Terminal и другие.
По сути, консоль находится под двойным управлением - приложения и оболочки, что является потенциально конфликтной ситуацией, в первую очередь в части использования кодировок.

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

Виды консолей

В общем случае функции консоли таковы:

управление операционной системой и системным окружением приложений на основе применения стандартных системных устройств ввода-вывода (экран и клавиатура), использования команд операционной системы и/или собственно консоли;

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

Отдельным видом консоли можно считать консоль отладки Visual Studio (CMD-D ).

Конфликт кодировок

Полностью локализованная консоль в идеале должна поддерживать все мыслимые и немыслимые кодировки приложений, включая свои собственные команды и команды Windows, меняя "на лету" кодовые страницы потоков ввода и вывода. Задача нетривиальная, а иногда и невозможная - кодовые страницы DOS (CP437, CP866) плохо совмещаются с кодовыми страницами Windows и Unicode.

Совет 1. Выполнять разработку текстовых файлов (программных кодов, текстовых данных и др.) исключительно в кодировке UTF-8. Мир любит Юникод, а кроссплатформенность без него вообще невозможна.

Совет 2. Периодически проверять кодировку, например в текстовом редакторе Notepad++. Visual Studio может сбивать кодировку, особенно при редактировании за пределами VS.

Поскольку в консоли постоянно происходит передача управления от приложений к собственно командному процессору и обратно, регулярно возникает "конфликт кодировок", наглядно иллюстрируемый таблица 1 и 2, сформированных следующим образом:

Команды и код приложения под катом

> Echo ffffff фффффф // в командной строке

PS> Echo ffffff фффффф // в PowerShell

PS> Echo ffffff . // так выглядит та же команда в Windows PowerShell

код тестового приложения:

Командную часть задания все консоли локализовали практически без сбоев во всех кодировках, за исключением: в WPS неверно отображена русскоязычная часть команды во всех кодировках.

Табл. 1. Результат выполнения команды консоли Echo ffffff фффффф

Табл. 1. Результат выполнения команды консоли Echo ffffff фффффф

Вывод тестового приложения локализован лишь в 50% испытаний, как показано в табл.2.

Табл. 2. Результат запуска приложения LoggingConsole.Test

Табл. 2. Результат запуска приложения LoggingConsole.Test

Сoвет 3. Про PowerShell забываем раз и навсегда. Ну может не навсегда, а до следующей мажорной версии.

По умолчанию Windows устанавливает для консоли кодовые страницы DOS. Чаще всего CP437, иногда CP866. Актуальные версии командной строки cmd.exe способны локализовать приложения на основе русифицированной кодовой страницы 866, но не 437, отсюда и изначальный конфликт кодировок консоли и приложения. Поэтому

Совет 4. Перед запуском приложения необходимо проверить кодовую страницу консоли командой CHCP и ей же изменить кодировку на совместимую - 866, 1251, 65001.

Проблемы консолей Visual Studio

В Visual Studio имеется возможность подключения консолей, по умолчанию подключены командная строка для разработчика и Windows PowerShell для разработчика. К достоинствам можно отнести возможности определения собственных параметров консоли, отдельных от общесистемных, а также запуск консоли непосредственно в директории разработки. В остальном - это обычные стандартные консоли Windows, включая, как показано ранее, установленную кодовую страницу по умолчанию.

Отдельной опцией Visual Studio является встроенная односеансная консоль отладки, которая перехватывает команду Visual Studio на запуск приложения, запускается сама, ожидает компиляцию приложения, запускает его и отдает ему управление. Таким образом, отладочная консоль в течение всего рабочего сеанса находится под управлением приложения и возможность использования команд Windows или самой консоли, включая команду CHCP, не предусмотрена. Более того, отладочная консоль не воспринимает кодовую страницу по умолчанию, определенную в реестре, и всегда запускается в кодировке 437 или 866.

Совет 6. Тестирование приложения целесообразно выполнять во внешних консолях, более дружелюбных к локализации.

Анализ проблем консолей был бы не полон без ответа на вопрос - можно ли запустить консольное приложение без консоли? Можно - любой файл ".exe" запустится двойным кликом, и даже откроется окно приложения. Однако консольное приложение, по крайней мере однопоточное, по двойному клику запустится, но консольный режим не поддержит - все консольные вводы-выводы будут проигнорированы, и приложение завершится

Локализация отладочной консоли 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 получает номера текущих страниц, устанавливает новые кодовые страницы вводного и выводного потоков, выполняет чтение с консоли и записывает выводную строку, содержащий русский текст, в том числе считанный с консоли, обратно в консоль. Операция повторяется несколько раз для всех основных кодовых страниц, упомянутых ранее.

приложение запущено в консоли с кодовыми страницами 1251 (строка 2);

приложение меняет кодовые страницы консоли (current, setted);

приложение остановлено в консоли с кодовыми страницами 1252 (строка 11, setted);

по окончании работы приложения изменения консоли сохраняются (строка 14 - Active codepage 1252);

Приложение адекватно локализовано только в случае совпадения текущих кодовых страниц консоли (setted 1251:1251) с начальными кодовыми страницами (строки 8 и 10).

Совет 7. Обязательный и повторный! Функции SetConsoleCP должны размещаться в коде до первого оператора ввода-вывода в консоль.

Стратегия локализации приложения в консоли

Удалить приложение PowerShell (если установлено), сохранив Windows PowerShell;

Установить в качестве кодовую страницу консоли по умолчанию CP65001 (utf-8 Unicode) или CP1251 (Windows-1251-Cyr), см. совет 5;

Разработку приложений выполнять в кодировке utf-8 Unicode;

Контролировать кодировку файлов исходных кодов, текстовых файлов данных, например с помощью Notepad++;

Реализовать программное управление локализацией приложения в консоли, пример ниже под катом:

Начинает локализацию переменных среды в пакетном файле. Локализация продолжится до тех пор, пока не встретится совпадающая команда endlocal или не будет достигнут конец пакетного файла.

Синтаксис

Параметры

Параметр Описание
енабликстенсионс Включает расширения команд до тех пор, пока не будет обнаружена соответствующая команда endlocal , независимо от значения параметра до выполнения команды setlocal .
дисабликстенсионс Отключает расширения команд до тех пор, пока не будет обнаружена соответствующая команда endlocal , независимо от значения параметра до выполнения команды setlocal .
енабледелайедекспансион Включает расширение переменной среды с задержкой до тех пор, пока не будет обнаружена соответствующая команда endlocal , независимо от значения параметра до выполнения команды setlocal .
дисабледелайедекспансион Отключает расширение переменной среды с задержкой до тех пор, пока не будет обнаружена соответствующая команда endlocal , независимо от значения параметра до выполнения команды setlocal .
/? Отображение справки в командной строке.

Комментарии

Если вы используете setlocal вне сценария или пакетного файла, он не оказывает никакого влияния.

Используйте команду setlocal для изменения переменных среды при запуске пакетного файла. Изменения среды, внесенные после выполнения команды setlocal , являются локальными для пакетного файла. Программа Cmd.exe восстанавливает предыдущие параметры при обнаружении команды endlocal или достижении конца пакетного файла.

В пакетной программе можно использовать несколько команд setlocal или endlocal (т. е. вложенные команды).

Команда setlocal задает переменную ERRORLEVEL. При передаче енабликстенсионс | дисабликстенсионс> или енабледелайедекспансион | дисабледелайедекспансион> переменной ERRORLEVEL присваивается значение 0 (ноль). В противном случае устанавливается значение 1. Эти сведения можно использовать в пакетных скриптах, чтобы определить, доступны ли расширения, как показано в следующем примере:

Поскольку при отключенных расширениях команд cmd не устанавливает переменную ERRORLEVEL, команда Verify ИНИЦИАЛИЗИРУет значение переменной ERRORLEVEL ненулевым значением при его использовании с недопустимым аргументом. Кроме того, если вы используете команду setlocal с аргументами енабликстенсионс | дисабликстенсионс> или енабледелайедекспансион | дисабледелайедекспансион> и не устанавливаете переменную ERRORLEVEL в значение 1, расширения команд недоступны.

Примеры

Для локализации переменных среды в пакетном файле используйте следующий пример скрипта:

Выполняю cmd и в нем set, хочу узнать USERNAME. Но оно показывается в непонятной кодировке.

chcp 866; chcp 1251; chcp 65001 - не помогали.

Оказывается надо в свойствах самого cmd выбрать шрифт Lucida Console. Только так можно получить нормальный текст на русском языке.

Спасшая статья:

Приложение cmd.exe – это командная строка или программная оболочка с текстовым интерфейсом (во загнул ).

Запустить командную строку можно следующим способом: ПускВыполнить → вводим в поле команду – cmd и жмем ОК. В итоге откроется рабочее окно программы – c:\WINDOWS\system32\cmd.exe. (рис.1)


Если Вы занялись проблемой кодировки шрифтов в cmd.exe , то как запускать командную строку наверняка уже знаете

Перейдем собственно к проблеме: иногда вместо русских букв при выполнении команд выходит набор непонятных символов (рис.2).


Первым делом нужно зайти в свойства окна – правой кнопкой щелкнуть по верхней части окна → Свойства → выйдет окно рис.3, здесь в поле Шрифтвыбираем Lucida Console и жмем ОК.


Теперь Вы получили нормальный текст на русском языке. Так же можно поменять текущую кодировку шрифта, для этого используется команда chcp. Набираем эту команду и жмем Enter, в результате получим текущую кодировку для командной строки – рис.4.


Для изменения кодировки так же применим chcp в следующем формате:

Chcp <код>

Где <код> – это цифровой параметр нужного шрифта, например,

1251 – Windows (кириллица);

866 – DOC-кодировка;

65001 – UTF-8;

Выбирайте на любой вкус. Т.о. что бы изменить кодировку на UTF-8 нужно выполнить команду chcp 65001.


almix
Разработчик Loco, автор статей по веб-разработке на Yii, CodeIgniter, MODx и прочих инструментах. Создатель Team Sense.

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