PowerShell (shell-based) solutions:
To determine the system locale's (system-wide) OEM code page - which is the one used by console applications, use the registry:
# $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)
Note:
Using the system-wide UTF-8 support also sets the ANSI code page (ACP
) to 65001
, used by legacy GUI applications but notably also Windows PowerShell[1], means that Windows PowerShell's default encoding for the Get-Content
and Set-Content
cmdlet, for instance, changes.
From cmd.exe
, you could run
reg.exe query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage /v OEMCP
, but you'd then have to parses its textual output to extract just the code page number.
Note that, regrettably, PowerShell's Get-WinSystemLocale
cmdlet cannot be used as of this writing, because the [cultureinfo]
instance it returns does not reflect a UTF-8 override that may be in place - see this ServerFault answer.
To determine the current console's active OEM code page - which may or may not reflect the system locale's, because console windows can be configured to use custom code pages, and the code page could even have been changed in-session beforehand:
# $true, if the OEM code page is set to UTF-8 (code page 65001)
65001 -eq [Console]::OutputEncoding.CodePage
Note:
- From
cmd.exe
you could execute chcp
chcp.com
, but you would then have to parse its textual output to extract just the code-page number
Windows API-based solution:
From a compiled application, you can use the the GetACP() and GetOEMCP() Windows API functions to query the active ANSI and OEM code page, respectively.
You could even do that from PowerShell (though the fact that it requires on-demand compilation makes the registry solution at the top preferable):
# 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()
Note:
- If your compiled application is a console application and you want to know the associated console's current OEM code page - which may or may not be the default page set via the system locale - use the
GetConsoleOutputCP()
function instead.
[1] The active ANSI code page is no longer relevant to PowerShell [Core] v6+, which consistently uses BOM-less UTF-8 for its cmdlets, but on Windows the active OEM code page, as reflected in [Console]::OutputEncoding
, still matters when communicating with external programs.