zHz00 Untitled

пятница, 27 октября 2023
03:04 Проблемы с локалью в Windows 10
Не все знают, что такое локаль. Если коротко -- это когда вы лезете в...

Settings ->
Time & Language ->
Language ->
Administrative language settings ->
Administrative (вкладка) ->
Change system locale

И начинаете там шуровать. Кто играл в визуальные новеллы на японском, знает, что тут надо ставить японский, но тогда перестанут работать русские не-юникод программы (точнее будут, но только с крякозябрами).

Если у вас тут стоит английский, то с русскими программами опять будет беда.

Я же столкнулся с ситуацией, когда локаль установлена русская, но проблемы всё равно есть. Не-юникод программы отображаются верно, хотя шрифты почему-то немного не те. А вот файлы... с файлами не всё в порядке.

1. Архивы, содержащие кириллические имена файлов, распаковываются в ромбики с вопросительными знаками.
2. Текстовые не-юникод файлы открываются вижуал студиями неправильно, тоже показывают квадратики. Хотя в ноутпад++ всё работает верно. Ну и не компилируется ничего с ошибкой newline in constant, хотя никаких новых строк в этих квадратиках нету.

На дворе 2k23, а мы всё ещё боремся с крякозябрами в винде? Это нонсенс.

В чём же было дело? Как раз в 2k23 годе. Виндоуз 10 кроме настройки локали имеет в том окошечке ещё один интересный параметр:

Beta: Use Unicode UTF-8 for worldwide language support.

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

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

В общем, я снял эту галочку. Перезагрузил. И файлы стали открываться нормально.

@темы: Лайфхак, Борьба с техникой

URL
Вэсна прышоль - лубит приньос! Всем девушкам гарнизо...
Шестнадцатилетний Дима выглядит очень серьезно и сосредот...
Молодая психиатр приходит в свое отделение. С порога все ...
http://www.scitoys.com/scitoys/scit...mo.html#rockets ...
Прислала девушка(имя и прочее осталось неизвестным) прочи...
Сегодня прочитал, что он умер 30 марта, аж 6 дней назад, ...

27.10.2023 в 15:25

27.10.2023 в 15:25
Потому, что - не знаю, насколько ты подробно это знаешь - в винде есть 2 версии большинства строковых API:

1. Обычная (например, GetWindowTextW), которая возвращает текст в UTF-16. Результат всегда состоит из двухбайтовых текстовых позиций, которые некоторые программы считают буквами.
2. И legacy, например, GetWindowTextA, в которой текст всегда состоит из однобайтовых позиций.

Поскольку внутри системы весь текст в UTF-16, функции типа *A это обёртки, и можно выбрать, в какую однобайтовую кодировку они будут превращать строку перед возвратом.

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

Точнее всего это назвать "Предполагаемой кодировкой для программ, которые не поддерживают юникод".

То есть, программа изначально юникод не поддерживает, но возможно, как-то справится с отдельной локалью, если в последний момент для неё лично данные в эту локаль перевести.

Галочка про UTF-8 на самом деле была всегда, только не была галочкой. Одна из доступных однобайтовых локалей это CP_UTF8. Все *A-функции начинают возвращать текст в UTF8.

Расчёт на то, что UTF-8 обратно совместим с ASCII (то есть, все байты UTF8 являются валидными ASCII-символами), и поэтому глупые старые программы подумают, что получили валидный странный текст! А когда передадут его в системные функции обратно, те (зная об UTF8), преобразуют его в правильный юникод.

Но, если внимательно посмотришь, ситуация не отличается от выбора в качестве Language for non-unicode programs, например, турецкого.

Если ты выберешь турецкий, всё устаревшее ПО начнёт считать все однобайтовые строки, которые находит на твоём компьютере (в том числе из файлов) турецкими. Оно будет передавать их в функции Windows, и Windows будет декодировать их как турецкую кодировку (ошибочно).

И если ты выберешь UTF-8, всё устаревшее ПО начнёт считать все однобайтовые данные из твоих файлов закодированными в UTF8 (ошибочно, поскольку они закодированы CP1251). Оно будет передавать их в функции Windows, и Windows будет декодировать их как UTF8 (ошибочно).

Разница только в том, что в турецкой кодировке ты не сможешь ввести японские символы в программу, которая работает через устаревшие API. А с кодировкой UTF8 сможешь. И во многих случаях всё будет работать нормально. Винда передаст программе странную однобайтовую строку, программа запишет её в файл (файл получится UTF8 без подписи), назавтра прочтёт, передаст винде, и на экране будет правильный текст.

Но работать это будет только с UTF8-файлами, как турецкая кодировка работает только с турецкими файлами.

Дополнительно дело усложняется тем, что даже нормальное ПО, когда читает неподписанные текстовые байты, должно пытаться угадать кодировку. И основной, а часто и единственный способ для однобайтовых кодировок - это предположить, что они в системной локали.

Поэтому и в Visual Studio ты видишь такое.

2023 год тут мало при чём, поскольку всё, что написано в 2023 году, и сохранено в UTF8/UTF16, будет открываться нормально. Если вам нужно будущее, оно давно наступило и юникод уже везде. Эта галочка это попытка немножко приспособить прошлое. (Ну и возможно, подтолкнуть людей, сохраняющих не в UTF8/UTF16, а в локальной кодировке, к прозрачному переходу на хранение в UTF8)
URL

27.10.2023 в 15:56

27.10.2023 в 15:56
himself, ультимативный ответ, спасибо!
URL

27.10.2023 в 17:30

27.10.2023 в 17:30
> ультимативный ответ, спасибо!
присоединяюсь к овациям
URL
Добавить комментарий

Расширенная форма

Подписаться на новые комментарии