Поделиться через


Использование кодовых страниц UTF-8 в приложениях Windows

Используйте формат преобразования Юникод (UTF-8), чтобы максимально обеспечить совместимость между веб-приложениями и другими платформами на основе *nix (Unix, Linux и их вариантов), минимизировать ошибки локализации и сократить затраты ресурсов на тестирование.

UTF-8 — это универсальная кодовая страница для интернационализации и может кодировать весь набор символов Юникода. Он широко используется в Интернете и является кодировкой по умолчанию для платформ XML и *nix.

Установка кодовой страницы процесса на UTF-8

Начиная с Версии Windows 1903 (обновление за май 2019 г.), можно указать свойство activeCodePage в appxmanifest для упакованных приложений (или манифест fusion для распакованных приложений), чтобы принудительно использовать UTF-8 в качестве кодовой страницы процесса.

Примечание.

Интерфейс графического устройства Windows (GDI) в настоящее время не поддерживает настройку свойства activeCodePage для каждого процесса. Вместо этого GDI по умолчанию использует активную системную кодовую страницу. Чтобы настроить приложение для отрисовки текста UTF-8 с помощью GDI, перейдите в и проверьте > Затем перезагрузите компьютер, чтобы изменения вступили в силу.

Можно объявить свойство activeCodePage и нацелиться на более ранние сборки Windows или выполнять на них запуск, но необходимо обрабатывать обнаружение и преобразование кодовой страницы прошлого как обычно. С минимальной целевой версией Windows версии 1903 кодовая страница процесса всегда будет иметь UTF-8, поэтому можно избежать обнаружения и преобразования устаревшей кодовой страницы.

Примечание.

В UTF-8 закодированный символ представлен последовательностью от 1 до 4 байтов. (См. определение D92 в главе 3стандарта Юникода для официальной спецификации.)

Примеры

Манифест Appx для упаковаемого приложения:

<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
         ...
         xmlns:uap7="http://schemas.microsoft.com/appx/manifest/uap/windows10/7"
         xmlns:uap8="http://schemas.microsoft.com/appx/manifest/uap/windows10/8"
         ...
         IgnorableNamespaces="... uap7 uap8 ...">

  <Applications>
    <Application ...>
      <uap7:Properties>
        <uap8:activeCodePage>UTF-8</uap8:activeCodePage>
      </uap7:Properties>
    </Application>
  </Applications>
</Package>

Манифест Fusion для распаковки приложения Win32:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity type="win32" name="..." version="6.0.0.0"/>
  <application>
    <windowsSettings>
      <activeCodePage xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage>
    </windowsSettings>
  </application>
</assembly>

Примечание.

Добавьте манифест в существующий исполняемый файл из командной строки mt.exe -manifest <MANIFEST> -outputresource:<EXE>;#1.

-A vs. -W API

API Win32 часто поддерживают варианты -A и -W.

-Варианты распознают кодовую страницу ANSI, настроенную в системе и char*поддержке, а варианты -W работают в UTF-16 и поддерживают WCHAR.

До недавнего времени Windows подчеркнула варианты Юникода через API-интерфейсы -A. Однако последние выпуски использовали кодовую страницу ANSI и API-интерфейсы -A в качестве средства для внедрения поддержки UTF-8 в приложения. Если кодовая страница ANSI настроена для UTF-8, API-интерфейсы обычно работают в UTF-8. Эта модель имеет преимущество поддержки существующего кода, созданного с помощью API -A без каких-либо изменений кода.

Преобразование кодовой страницы

Так как Windows работает изначально в UTF-16 (WCHAR), может потребоваться преобразовать данные UTF-8 в UTF-16 (или наоборот), чтобы взаимодействовать с API Windows.

MultiByteToWideChar и WideCharToMultiByte позволяют преобразовать между UTF-8 и UTF-16 () (WCHARи другими кодовыми страницами). Это особенно полезно, если устаревший API Win32 может только понять WCHAR. Эти функции позволяют преобразовать входные данные UTF-8 для WCHAR передачи в API -W, а затем при необходимости преобразовать все результаты.

Использование dwFlags либо 0MB_ERR_INVALID_CHARS при использовании этих функций с CodePage заданным значением CP_UTF8 (в противном случае ERROR_INVALID_FLAGS происходит).

Примечание.

CP_ACP соответствует CP_UTF8 только в том случае, если программа выполняется в системе Windows версии 1903 (обновление за май 2019 г.) или выше и свойству activeCodePage, описанному выше, присвоено значение UTF-8. В противном случае она учитывает устаревшую системную кодовую страницу. Мы рекомендуем использовать CP_UTF8 явно.