Script per rilevare se Windows System Locale utilizza la codepage UTF-8?
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
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) su65001, utilizzata dalle applicazioni GUI legacy ma in particolare anche da Windows PowerShell [1] , significa che la codifica predefinita di Windows PowerShell per il cmdletGet-ContenteSet-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 eseguirechcpchcp.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 .