在 Windows 應用程式中使用 UTF-8 字碼頁

使用 UTF-8 字元編碼可實現 Web 應用程式和其他基於 *nix 的平台 (Unix、Linux 及其變體) 之間的最佳相容性,最大限度地減少本地化錯誤並減少測試開銷。

UTF-8 是國際化的通用代碼頁,能夠編碼整個 Unicode 字元集。 它在網路上廣泛使用,並且是基於 *nix 的平台的預設設定。

將程序代碼頁設定為 UTF-8

從 Windows 版本 1903 (2019 年 5 月更新) 開始,您可以在打包應用程式的 appxmanifest 或未打包應用程式的融合清單中使用 ActiveCodePage 屬性,強制進程使用 UTF-8 作為進程代碼頁。

注意

GDI 目前不支援為每個進程設定 ActiveCodePage 屬性。 相反地,GDI 預設為使用中的系統代碼頁。 若要將您的應用程式配置為透過 GDI 呈現 UTF-8 文本,請前往 Windows 設定>時間&語言>語言&區域>管理語言設定>變更系統區域設置,然後選取 Beta:使用 Unicode UTF-8 取得全球語言支援。 然後重新啟動電腦以使更改生效。

您可以宣告 ActiveCodePage 屬性,並在舊版 Windows 組建上設定目標/執行,但您必須像往常一樣處理舊版代碼頁偵測和轉換。 使用 Windows 版本 1903 的最低目標版本,程式代碼頁一律會是 UTF-8,因此可以避免舊版代碼頁偵測和轉換。

注意

編碼字元需要 1 到 4 個字節。 UTF-8 編碼支援較長的位元組序列,最多 6 個字節,但 Unicode 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>

解除封裝 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 與 -W API

Win32 API 通常同時支援 -A 和 -W 變體。

-A 變體識別系統上配置的 ANSI 代碼頁並支持,char*而 -W 變體以 UTF-16 執行並支援WCHAR

直到最近,Windows 在 -A API 上強調「Unicode」-W 變體。 不過,最新版本已使用 ANSI 代碼頁和 -A API 作為向應用程式引進 UTF-8 支援的方法。 如果 ANSI 代碼頁已設定為 UTF-8,則 -A API 通常會在 UTF-8 中運作。 此模型的優點是支援使用 -A API 建立的現有程式碼,而無需更改任何程式碼。

代碼頁轉換

由於 Windows 本身以 UTF-16 (WCHAR) 執行,因此您可能需要將 UTF-8 資料轉換為 UTF-16 (反之亦然) 才能與 Windows API 進行互通。

MultiByteToWideCharWideCharToMultiByte 允許您在 UTF-8 和 UTF-16 (WCHAR) (以及其他代碼頁) 之間進行轉換。 當舊版 Win32 API 可能只瞭解 WCHAR時,這特別有用。 這些函數允許您將 UTF-8 輸入轉換為 WCHAR 傳遞到 -W API,然後在必要時將任何結果轉換回來。

當使用 dwFlags 這些函式搭配 0 設定為 MB_ERR_INVALID_CHARS 時,請使用 CodePageCP_UTF8,否則ERROR_INVALID_FLAGS 會發生。

注意

只有在 Windows 版本 1903 (2019 年 5 月更新) 或更高版本上執行且上述 ActiveCodePage 屬性設定為 UTF-8 時,CP_ACP 才相當於 CP_UTF8。 否則,它會接受舊版系統代碼頁。 我們建議明確地使用 CP_UTF8