Skript zum Erkennen, ob das Windows-Systemgebietsschema die UTF-8-Codepage verwendet?

Nov 21 2020

In neueren Versionen von Win10 ist es möglich, die Active Code Page (ACP) auf eine UTF-8-Codepage festzulegen. Wie hier erläutert , ist es möglich, das Systemgebietsschema (das zum Zuordnen zwischen der "A" -Version und der "W" -Version der Windows-API verwendet wird) für die Verwendung der UTF-8-Codepage festzulegen.

Wie erkennt ein Skript, ob die UTF-8-Codepage verwendet wird?

Wie hier und hier erläutert , ist es normalerweise möglich, WMI zu verwenden, um die Systemcodepage-ID abzurufen:

For Each os In wmi.ExecQuery("SELECT * FROM Win32_OperatingSystem")
    cs = os.CodeSet
Next

Wenn ich das unter Win10 versuche und die Beta-Unterstützung von utf-8 in amerikanischem Englisch für Nicht-Unicode-Programme verwende, meldet WMI weiterhin, dass die Codepage 1252 ist. Auch wenn dies eindeutig nicht der Fall ist (Codepage 1252) ein Codepunkt bei 128, aber keiner bei 49800: UTF-8 hat einen Codepunkt bei 49800, keiner bei 128).

Wie erkennt ein Skript, dass das tatsächliche Systemgebietsschema die UTF-8-Codepage verwendet?

Antworten

4 mklement0 Nov 21 2020 at 12:19

PowerShell-Lösungen (Shell-basiert):

Verwenden Sie die Registrierung, um die (systemweite) OEM-Codepage des Systemgebietsschemas zu ermitteln, die von Konsolenanwendungen verwendet wird:

# $true, if the OEM code page is set to UTF-8 (code page 65001)
'65001' -eq (Get-ItemPropertyValue HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage OEMCP)

Hinweis:

  • Mit Hilfe der systemweiten UTF-8 - Unterstützung setzt auch die ANSI - Codepage ( ACP) auf 65001, durch verwendet Legacy - GUI - Anwendungen , sondern vor allem auch Windows Powershell [1] , bedeutet , dass Windows Powershell der Standard - Kodierung für die Get-Contentund Set-ContentCmdlets zum Beispiel Änderungen.

  • Von cmd.exekönnten Sie ausführen
    reg.exe query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage /v OEMCP, müssten dann aber die Textausgabe analysieren, um nur die Codepage-Nummer zu extrahieren.

  • Beachten Sie, dass bedauerlicherweise Powershell Get-WinSystemLocalekann Cmdlets nicht zum Zeitpunkt des Schreibens verwendet werden, da die [cultureinfo]Instanz es gibt nicht nicht UTF-8 - Überschreibung widerspiegelt , die an Ort und Stelle sein können - siehe diese ServerFault Antwort .


So ermitteln Sie die aktive OEM-Codepage der aktuellen Konsole - die möglicherweise das Gebietsschema des Systems widerspiegelt oder nicht, da Konsolenfenster für die Verwendung benutzerdefinierter Codepages konfiguriert werden können und die Codepage möglicherweise sogar zuvor in der Sitzung geändert wurde:

# $true, if the OEM code page is set to UTF-8 (code page 65001)
65001 -eq [Console]::OutputEncoding.CodePage

Hinweis:

  • Von cmd.exekönnten Sie ausführen chcp chcp.com, aber Sie müssten dann seine Textausgabe analysieren, um nur die Codepage-Nummer zu extrahieren

Windows API-basierte Lösung :

In einer kompilierten Anwendung können Sie die Windows-API-Funktionen GetACP () und GetOEMCP () verwenden, um die aktive ANSI- bzw. OEM-Codepage abzufragen.

Sie können dies sogar mit PowerShell tun (obwohl die Registrierungslösung oben aufgrund der Tatsache, dass eine On-Demand-Kompilierung erforderlich ist, vorzuziehen ist):

# Compile a helper type that calls the WinAPI functions.
Add-Type -Namespace Util -Name WinApi -MemberDefinition @'
  [DllImport("Kernel32.dll")]
  public static extern uint GetACP();
  [DllImport("Kernel32.dll")]
  public static extern uint GetOEMCP();
'@

[Util.WinAPI]::GetOEMCP(), [Util.WinAPI]::GetACP()

Hinweis:

  • Wenn Ihre kompilierte Anwendung eine Konsolenanwendung ist und Sie die aktuelle OEM-Codepage der zugehörigen Konsole kennen möchten - die möglicherweise die über das Systemgebietsschema festgelegte Standardseite ist oder nicht -, verwenden Sie GetConsoleOutputCP()stattdessen die Funktion.

[1] Die aktive ANSI-Codepage ist für PowerShell [Core] v6 + nicht mehr relevant , das für seine Cmdlets konsequent UTF-8 ohne Stückliste verwendet. Unter Windows ist die aktive OEM-Codepage, wie in dargestellt [Console]::OutputEncoding, bei der Kommunikation mit weiterhin wichtig externe Programme .