Script per rilevare se Windows System Locale utilizza la codepage UTF-8?

Nov 21 2020

Nelle versioni recenti di Win10 è possibile impostare la code page attiva (ACP) su una code page UTF-8. E come discusso qui , è possibile impostare le impostazioni internazionali del sistema (utilizzate per eseguire il mapping tra la versione "A" e la versione "W" dell'API di Windows) per utilizzare la codepage UTF-8.

In che modo uno script rileva se la codepage UTF-8 è in uso?

Come discusso qui e qui , è normalmente possibile utilizzare WMI per ottenere l'ID della tabella codici di sistema:

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

Quando lo provo su Win10, impostato per utilizzare il supporto 'beta' utf-8 in inglese americano per programmi non unicode, WMI continua a segnalare che la tabella codici è 1252. Anche se chiaramente non è così (la tabella codici 1252 ha un punto di codice a 128, ma nessuno a 49800: UTF-8 ha un punto di codice a 49800, nessuno a 128).

In che modo uno script rileva che le impostazioni internazionali effettive del sistema utilizzano la codepage UTF-8?

Risposte

4 mklement0 Nov 21 2020 at 12:19

Soluzioni PowerShell (basate su shell):

Per determinare la codepage OEM delle impostazioni locali del sistema (a livello di sistema) , che è quella utilizzata dalle applicazioni della console , utilizzare il registro:

# $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)

Nota:

  • L'utilizzo del supporto UTF-8 a livello di sistema imposta anche la code page ANSI ( ACP) su 65001, utilizzata dalle applicazioni GUI legacy ma in particolare anche da Windows PowerShell [1] , significa che la codifica predefinita di Windows PowerShell per il cmdlet Get-Contente Set-Content, ad esempio, cambia.

  • Da cmd.exe, potresti eseguire
    reg.exe query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage /v OEMCP, ma dovresti quindi analizzare il suo output testuale per estrarre solo il numero di code page.

  • Si noti che, purtroppo, il Get-WinSystemLocalecmdlet di PowerShell non può essere utilizzato al momento della stesura di questo documento, perché l' [cultureinfo]istanza restituita non riflette una sostituzione UTF-8 che potrebbe essere in atto - vedere questa risposta ServerFault .


Per determinare la codepage OEM attiva della console corrente, che potrebbe riflettere o meno le impostazioni internazionali del sistema, poiché le finestre della console possono essere configurate per utilizzare le codepage personalizzate e la codepage potrebbe anche essere stata modificata in sessione in anticipo:

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

Nota:

  • Da cmd.exevoi potreste eseguire chcp chcp.com, ma dovreste poi analizzare il suo output testuale per estrarre solo il numero della code page

Soluzione basata su API di Windows :

Da un'applicazione compilata, è possibile utilizzare le funzioni API di Windows GetACP () e GetOEMCP () per interrogare rispettivamente la tabella codici ANSI e OEM attiva.

Puoi anche farlo da PowerShell (sebbene il fatto che richieda la compilazione su richiesta rende preferibile la soluzione del registro in alto):

# 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()

Nota:

  • Se l'applicazione compilata è un'applicazione console e si desidera conoscere la code page OEM corrente della console associata, che può essere o meno la pagina predefinita impostata tramite le impostazioni internazionali del sistema, utilizzare GetConsoleOutputCP()invece la funzione.

[1] La tabella codici ANSI attiva non è più rilevante per PowerShell [Core] v6 + , che utilizza in modo coerente UTF-8 senza BOM per i suoi cmdlet, ma su Windows la tabella codici OEM attiva, come indicato in [Console]::OutputEncoding, è ancora importante quando si comunica con programmi esterni .