Windows 10支持自定义区域设置,这些区域设置没有LCID,例如旧版Windows中的旧版本区域设置。在Windows 10的每次更新中,Microsoft一直在为少数民族和土着语言添加较少使用的语言环境。
Windows 10的最新更新添加了Võrokii(vro
)语言环境。使用EnumSystemLocalesEx
枚举所有支持的区域设置时,vro
不会以任何形式显示。但是,在用于添加新语言或键盘的系统设置UI中,确实会出现Võrokiil。
但是,如果用户随后启用了此语言,则当您拨打EnumSystemLocalesEx
时,vro
,vro-Latn
和vro-Latn-001
现已列出。如果用户随后从UI中删除了此区域设置,则它不再出现在此函数调用的结果中。
问题:是否有办法(支持或以其他方式)获取操作系统中所有已知语言环境的列表,无论用户是否已启用它们?
我发现这个输出包括Skolt Sami等其他少数民族语言而不要求用户提前启用它,这一点非常奇怪。
如果在C / C ++ API中不存在API,我将非常高兴地接受使用.NET框架的答案,只要我能够真正获得此数据。
生成语言环境输出的示例代码:
#include <cstdio>
#include "stdafx.h"
#include "windows.h"
BOOL CALLBACK Callback(LPWSTR pStr, DWORD dwFlags, LPARAM lparam)
{
wprintf(L"%ls\n", pStr);
return TRUE;
}
int main()
{
EnumSystemLocalesEx(Callback, 0, 0, 0);
return 0;
}
通过系统设置中的“地区和语言”屏幕启用Võrokii,最后三个结果为vro-Latn
,vro-Latn-001
和vro
。未启用时,它们根本不会出现在输出中。
使用.NET API似乎具有相同的行为。
#include "stdafx.h"
using namespace System;
using namespace System::Globalization;
int main()
{
System::Collections::IEnumerator^ enum0 = CultureInfo::GetCultures(CultureTypes::AllCultures)->GetEnumerator();
while (enum0->MoveNext())
{
CultureInfo^ ci = safe_cast<CultureInfo^>(enum0->Current);
Console::WriteLine("{0}", ci->Name);
}
}
答案 0 :(得分:0)
实际上,用于Windows的新语言模型意味着除了具有历史LCID的语言列表之外,没有“列表”。
Windows 8.1和10设置工具链接到bcp47langs.dll
和winlangdb.dll
,只要提供的输入是有效的ISO 639-3语言代码,它们就会提供用于启用语言和输入法的功能。 / p>
在某些情况下,如果希望您的语言出现在UI中或通过这些API出现,则必须至少提供脚本,有时甚至还提供区域。一个示例是myv-Cyrl
的Erzya语言。
在与PowerShell捆绑在一起的cmdlet上使用MSIL反汇编程序,我发现了p / invoke定义,它使我能够成功地使用C#和Rust代码中的这些API。
在这里,为后代:
// Decompiled with JetBrains decompiler
// Type: Microsoft.InternationalSettings.Commands.LPAPIWrapper
// Assembly: Microsoft.InternationalSettings.Commands, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// MVID: E0B49792-544F-4FBD-8C35-D4DA177385AF
// Assembly location: C:\Windows\Microsoft.NET\assembly\GAC_MSIL\Microsoft.InternationalSettings.Commands\v4.0_3.0.0.0__31bf3856ad364e35\Microsoft.InternationalSettings.Commands.dll
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace Microsoft.InternationalSettings.Commands
{
internal class LPAPIWrapper
{
public static uint GEO_NATION = 1;
public static uint GEO_FRIENDLYNAME = 8;
public static uint GEOCLASS_NATION = 16;
public static uint GEOCLASS_REGION = 14;
[DllImport("kernelbase.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int NlsUpdateLocale(string LocaleName, int Flags);
[DllImport("intl.cpl", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int IntlUpdateSystemLocale(string LocaleName, int dwFlags);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SystemParametersInfo(
uint Action,
uint UnsignedParam,
IntPtr Param,
uint WinIni);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SendNotifyMessage(
IntPtr wWwnd,
uint Msg,
IntPtr wParam,
string lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetSystemDefaultLocaleName(
StringBuilder LocaleName,
int LocaleNameSize);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetUserGeoID(uint GeoClass);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SetUserGeoID(int GeoId);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetGeoInfo(
int Location,
uint GeoType,
StringBuilder GeoData,
int Length,
ushort LangID);
[DllImport("bcp47langs.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetUserLanguages(char Delimiter, [MarshalAs(UnmanagedType.HString)] ref string UserLanguages);
[DllImport("bcp47langs.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetUserLanguageInputMethods(
string Language,
char Delimiter,
[MarshalAs(UnmanagedType.HString)] ref string InputMethods);
[DllImport("bcp47langs.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int LcidFromBcp47([MarshalAs(UnmanagedType.HString)] string LanguageTag, ref int Lcid);
[DllImport("bcp47langs.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetPendingUserDisplayLanguage([MarshalAs(UnmanagedType.HString)] ref string language);
[DllImport("bcp47langs.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetUserDisplayLanguageOverride([MarshalAs(UnmanagedType.HString)] ref string language);
[DllImport("bcp47langs.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SetUserDisplayLanguageOverride(string LanguageTag);
[DllImport("bcp47langs.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int ClearUserDisplayLanguageOverride();
[DllImport("bcp47langs.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetHttpAcceptLanguageOptOut(ref bool IsOptOut);
[DllImport("bcp47langs.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SetHttpAcceptLanguageOptOut();
[DllImport("bcp47langs.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int ClearHttpAcceptLanguageOptOut();
[DllImport("bcp47langs.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetUserLocaleFromLanguageProfileOptOut(ref bool IsOptOut);
[DllImport("bcp47langs.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SetUserLocaleFromLanguageProfileOptOut();
[DllImport("bcp47langs.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int ClearUserLocaleFromLanguageProfileOptOut();
[DllImport("bcp47langs.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int RemoveInputsForAllLanguagesInternal();
[DllImport("bcp47langs.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SetInputMethodOverride(string TipString);
[DllImport("bcp47langs.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int Bcp47GetIsoLanguageCode([MarshalAs(UnmanagedType.HString)] string languageTag, [MarshalAs(UnmanagedType.HString)] ref string isoLanguageCode);
[DllImport("ext-ms-win-globalization-input-l1-1-2.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int WGIGetDefaultInputMethodForLanguage(
[MarshalAs(UnmanagedType.HString)] string Language,
[MarshalAs(UnmanagedType.HString)] ref string DefaultTipString);
[DllImport("ext-ms-win-globalization-input-l1-1-2.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int WGITransformInputMethodsForLanguage(
[MarshalAs(UnmanagedType.HString)] string TipString,
[MarshalAs(UnmanagedType.HString)] string Language,
[MarshalAs(UnmanagedType.HString)] ref string TransformedTipString);
[DllImport("winlangdb.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SetUserLanguages(char Delimiter, [MarshalAs(UnmanagedType.HString)] string UserLanguages);
[DllImport("winlangdb.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetLanguageNames(
string Language,
StringBuilder Autonym,
StringBuilder EnglishName,
StringBuilder LocalName,
StringBuilder ScriptName);
[DllImport("ext-ms-win-globalization-input-l1-1-2.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int WGIIsImeInputMethod([MarshalAs(UnmanagedType.HString)] string TipString, ref int result);
[DllImport("winlangdb.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int EnsureLanguageProfileExists();
[DllImport("input.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int InstallLayoutOrTip(string TipString, int Flags);
[DllImport("input.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SetDefaultLayoutOrTip(string TipString, int Flags);
[DllImport("input.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetLayoutDescription(
string LayoutId,
StringBuilder LayoutDescription,
ref int DescriptionLength);
private LPAPIWrapper()
{
}
}
}