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

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

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

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

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

Примечание.

GDI в настоящее время не поддерживает настройку свойства ActiveCodePage для каждого процесса. Вместо этого GDI по умолчанию использует активную системную кодовую страницу. Чтобы настроить приложение для отображения текста UTF-8 с помощью GDI, перейдите к Windows Параметры> Time и языку и региону> Администратор istrative language>settings>Change system locale, and проверка Beta: Use Unicode UTF-8 for worldwide language support. Затем перезагрузите компьютер, чтобы изменения вступили в силу.

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

Примечание.

Закодированный символ занимает от 1 до 4 байтов. Кодировка UTF-8 поддерживает более длинные последовательности байтов, до 6 байтов, но самая большая кодовая точка Юникода 6.0 (U+10FFFF) занимает только 4 байта.

Примеры

Манифест 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 явно.