WindowsシステムロケールがUTF-8コードページを使用しているかどうかを検出するスクリプト?
Win10の最近のバージョンでは、アクティブコードページ(ACP)をUTF-8コードページに設定することができます。また、ここで説明するように、UTF-8コードページを使用するようにシステムロケール(Windows APIの「A」バージョンと「W」バージョンの間のマッピングに使用)を設定することができます。
スクリプトは、UTF-8コードページが使用されているかどうかをどのように検出しますか?
こことここで説明したように、通常はWMIを使用してシステムコードページIDを取得できます。
For Each os In wmi.ExecQuery("SELECT * FROM Win32_OperatingSystem")
cs = os.CodeSet
Next
非ユニコードプログラムに対してアメリカ英語で「ベータ」utf-8サポートを使用するように設定されたWin10でそれを試してみると、WMIはコードページが1252であると報告し続けます。コードポイントは128ですが、49800にはありません:UTF-8のコードポイントは49800にあり、128にはありません)。
スクリプトは、実際のシステムロケールがUTF-8コードページを使用していることをどのように検出しますか?
回答
PowerShell(シェルベース)ソリューション:
決定するためのシステムロケールの(システム全体)OEMコードページ-で使用されるものであり、コンソールアプリケーション、レジストリを使用します。
# $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)
注意:
使用してシステム全体のUTF-8をサポートも(ANSIコードページを設定
ACP
)する65001
ことにより、使用、従来のGUIアプリケーションが、特にもWindows PowerShellの[1]のWindows PowerShellの既定のためにエンコードすることを意味し、Get-Content
そしてSet-Content
例えば、コマンドレットは変化します。から
cmd.exe
、を実行できますが
reg.exe query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage /v OEMCP
、そのテキスト出力を解析して、コードページ番号のみを抽出する必要があります。残念ながら、PowerShellのGet-WinSystemLocaleコマンドレットは、この記事の執筆時点では使用できません。
[cultureinfo]
返されるインスタンスは、配置されている可能性のあるUTF-8オーバーライドを反映していないためです。このServerFaultの回答を参照してください。
現在のコンソールのアクティブなOEMコードページを判別するには-コンソールウィンドウはカスタムコードページを使用するように構成でき、コードページはセッション中に事前に変更されている可能性があるため、システムロケールを反映している場合と反映していない場合があります。
# $true, if the OEM code page is set to UTF-8 (code page 65001)
65001 -eq [Console]::OutputEncoding.CodePage
注意:
- から
cmd.exe
実行することもできchcp
chcp.com
ますが、そのテキスト出力を解析して、コードページ番号だけを抽出する必要があります。
Windows APIベースのソリューション:
コンパイルされたアプリケーションから、GetACP()およびGetOEMCP() Windows API関数を使用して、アクティブなANSIおよびOEMコードページをそれぞれクエリできます。
PowerShellからそれを行うこともできます(ただし、オンデマンドコンパイルが必要であるため、レジストリソリューションが最上位にあることが望ましいです)。
# 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()
注意:
- コンパイルされたアプリケーションがコンソールアプリケーションであり、関連するコンソールの現在のOEMコードページ(システムロケールを介して設定されたデフォルトページである場合とそうでない場合があります)を知りたい場合は、GetConsoleOutputCP()代わりに関数を使用してください。
[1]アクティブなANSIコードページはPowerShell [Core] v6 +とは関係がなくなり、コマンドレットにBOMのないUTF-8を一貫して使用しますが、Windowsでは、に反映されているように[Console]::OutputEncoding
、アクティブなOEMコードページは通信時に引き続き重要です。外部プログラム。