PowerShell UICulture 与 Windows 设置
Posted
技术标签:
【中文标题】PowerShell UICulture 与 Windows 设置【英文标题】:PowerShell UICulture vs. Windows setting 【发布时间】:2020-07-15 07:26:54 【问题描述】:在我在 Win 10 下修改 PS 5.1 的过程中,与问题Fully change language (including Culture) for the current PowerShell session 的目标有关, 我遇到了几个相关的问题。
与 UICulture 关联的 Windows 设置在哪里? 我没有找到“区域和语言”控制面板的“键盘和语言”选项卡,如here所示。
这可以在 PS 中持续更改吗? 到目前为止,我发现的所有内容都只存在于会话中。
设置设置 -> 时间和语言 -> 语言 -> Windows显示语言显示“Español (España)”,PS 给出了
> Get-UICulture ; [System.Threading.Thread]::CurrentThread.CurrentUICulture ; [CultureInfo]::CurrentUICulture ;
LCID Name DisplayName
---- ---- -----------
1033 en-US English (United States)
1033 en-US English (United States)
1033 en-US English (United States)
没有任何干预更改,并且在刚刚启动的会话中。
【问题讨论】:
【参考方案1】:在 .NET 中,cultures (System.Globalization.CultureInfo
) 用于控制 两个相关但独立的方面(人类) 特定文化用于展示的表示:
有效的UI 文化,反映在[cultureinfo]::CurrentUICulture
中,控制着应该用于UI 的(人类)语言元素和最终用户消息,例如错误消息。
在 Windows 上,它的值继承自所谓的 Windows 显示语言,这是一种持久的、用户特定的设置您可以按如下所述进行修改。
在 PowerShell 中,您还可以通过自动 $PSUICulture
变量(仅报告文化 name)或 Get-UICulture
cmdlet(报告 [cultureinfo]
实例)查询有效的 UI 文化。 警告:在 Windows PowerShell 中,报告的值是在 会话启动时间 生效的值(即then-current 持久值),因此任何会话中的更改都不会反映出来。此问题已在 PowerShell [Core] v6+ 中得到纠正。
有效的文化(反映在[cultureinfo]::CurrentCulture
)控制用于表示数字、货币价值和日期/时间值的格式 .
在 Windows 上,它的值继承自活动的区域设置,也就是区域格式,它们是持久的、特定于用户的您可以按如下所述修改的设置。
在 PowerShell 中,您还可以通过自动 $PSCulture
变量(仅报告文化名称)Get-Culture
cmdlet(报告[cultureinfo]
实例)查询有效的 UI 文化。警告:在 Windows PowerShell 中,报告的值是在会话启动时间有效的值,因此任何会话中更改没有反映。此问题已在 PowerShell [Core] v6+ 中得到纠正。
切换到不同的文化:
交互式 (GUI) 方法,对于当前用户来说总是持久:
UI 文化,又称 Windows 显示语言:
在 Windows 10 上,打开设置应用程序(例如,通过开始菜单),转到类别Time & Language
,然后点击左侧边栏中的Language
。
快捷方式:
快速打开设置应用:
使用键盘快捷键WinKey-i。 运行start ms-settings:
(也可以从 cmd
运行)。
在“开始”菜单中,只需键入“语言”并从结果中选择 Language Settings
- 这会将您直接带到“设置”应用中的相关页面。
运行intl.cpl
以打开旧版Region
控制面板小程序并单击Language preferences
链接,这会将您带到“设置”应用中的相关页面。
文化,又名区域格式(语言环境):
在 Windows 10 上,打开 设置应用程序(例如,通过开始菜单),转到类别 Time & Language
,然后单击左侧边栏中的 Region
,然后选择所需的Regional format
下的文化(顶部的Region
设置不控制文化)。
快捷方式:
在“开始”菜单中,只需键入“区域格式”并从结果中选择 Set regional format
- 这会将您直接带到“设置”应用中的相关页面。
运行intl.cpl
以打开旧版Region
控制面板小程序并从Format:
下拉列表中选择所需的文化。
注意:
这些设置同样适用于 .NET 和非 .NET 应用程序,假设这些应用程序旨在尊重用户的区域格式(区域设置、文化)和显示语言(UI 文化)并带有特定于语言的资源。
相比之下,通过[cultureinfo]::CurrentUICulture
/[cultureinfo]::CurrentCulture
(见下文)进行仅在会话中的更改仅适用于 .NET 应用程序。
程序化方法:
持续的当前用户更改(GUI 方法的等效项):
UI 文化,又称 Windows 显示语言:
有 no cmdlet,但在 Windows 8 / Windows Server 2012 R2 及更高版本中,您可以使用
Set-UICulture
Set-WinUILanguageOverride
cmdlet。
请注意,与目标文化相关的语言的语言包必须是系统自带的,或者必须事先下载。
重要提示:在您注销并重新登录或重新启动之前,更改不会生效。
文化,又名区域格式(语言环境):
使用Set-Culture
cmdlet,在 Windows 8 / Windows Server 2012 R2 及更高版本中可用。
重要提示:更改仅在未来 PowerShell 会话中生效,但不需要注销/重新启动。
仅限会话中更改:
重要提示:此类更改仅适用于基于.NET的应用程序。因此,从更改了区域性的 PowerShell 会话中调用非 .NET 控制台应用程序对该控制台应用程序没有影响。但是,更改确实对 PowerShell cmdlet、脚本和函数的调用生效。即使更改的范围在技术上仅限于 当前线程,PowerShell 也会将更改传播到在 new 线程(Start-ThreadJob
和 ForEach-Object -Parallel
)中执行的代码以及通过 PowerShell 远程处理在远程机器上执行的代码(例如,Invoke-Command
)。然而,奇怪的是,从 PowerShell 7.0 开始,在子进程中运行的后台作业 (Start-Job
)不继承调用线程的文化 - 见this GitHub issue。
您可以分配到[cultureinfo]::CurrentUICulture
/ [cultureinfo]::CurrentCulture
以更改当前线程的UI文化/文化(仅限,非永久);例如,以下命令使用法国文化输出当前日期和时间:
[cultureinfo]::CurrentCulture = 'fr-FR'; Get-Date
警告:由于 Windows PowerShell 中的错误,[cultureinfo]::CurrentUICulture
和 [cultureinfo]::CurrentCulture
被意外重置为会话启动值 > 在每个交互式提交的命令之后;此问题已在 PowerShell [Core] v6+ 中修复 - 请参阅 this answer。
结果是,如果您想使用与持久配置不同的文化来运行整个 PowerShell 会话,您可以将分配给 [cultureinfo]::CurrentUICulture
和 [cultureinfo]::CurrentCulture
放在您的 $PROFILE
文件中在 PowerShell [Core] v6+ 中,但您需要 Windows PowerShell 的解决方法 - 请参阅 this answer。
$PSUICulture
和$PSCulture
,因此这些变量不会反映解决方法(依赖于修改非公开字段)设置的有效文化;但是,Get-UICulture
/ Get-Culture
以及 [cultureinfo]::CurrentUICulture
/ [cultureinfo]::CurrentCulture
可以。
【讨论】:
【参考方案2】:这个答案是对that by mklement0 的补充。 PS 会话中的设置继承自 Win 设置 -> 时间和语言 -> 语言 -> Windows 的显示语言 在开始会话时。
因此,要为所有会话“永久”更改此设置,必须更改 Windows 设置。
或者,可以在profile.ps1
中change this only for the PS session,这不会“污染”Windows 配置。
我不确定这是否可以通过直接从 PS 访问 HKEY_CURRENT_USER\Control Panel\International
([ref])(或 HKEY_CURRENT_USER\Volatile Environment
?)来管理。
请注意,(在 Windows PowerShell 中)$PSUICulture
在上次 Windows 登录时通过检索上述 Windows 设置进行静态初始化。
因此它对当前的 PS 设置不敏感(可能在当前 PS 会话期间更改)。
所以$PSUICulture
可能与Get-UICulture
不同。
这不适用于 PowerShell Core。
【讨论】:
好点;我已经重组了我的答案以包含其中的大部分。我不建议直接处理注册表,因为更改文化会改变一大堆注册表值。至于$PSUICulture
/ $PSCulture
/ Get-UICulture
/ Get-Culture
反映了什么:在 PowerShell [Core] v6+ 中,它们 - 明智地 - 反映了当前有效的值。不幸的是,在 Windows PowerShell 中,它们总是反映会话启动时的值。
我在答案中添加了一段关于会话中文化变化范围的段落,其中包括发现令人惊讶的不一致之处。我之前的评论暗示了这一点,但要明确指出:“所以 $PSUICulture 可能与 Get-UICulture 不同”。不正确:对于给定的版本,结果始终相同(数据类型除外),但版本的不同之处在于它们报告的值(PSCore 中的当前值,WinPS 中的会话启动值)。您能否更正这一点,或者,鉴于我现在的回答有望讲述完整的故事,请考虑删除您的回答?
@mklement0 - 这就是我所看到的。 > $PSUICulture ; Get-UICulture <br> es-ES <br> LCID Name DisplayName <br> ---- ---- ----------- <br> 1033 en-US English (United States) <br>
为什么说我的说法不正确?也许我应该改写“$PSUICulture
的屏幕输出可能与Get-UICulture
不同”?
1) > $PSUICulture ; (Get-UICulture).Name <br> es-ES <br> en-US
在 [cultureinfo]::CurrentUICulture = <culture> ;
前面加上 'en-US'
、'es-ES'
、'es-AR'
、2) Set-PowerShellUICulture
中加载的脚本 profile.ps1
、3 ) PS 5.1.17763.1007
我明白了——那是完全因为Set-PowerShellUICulture
构成的hack(修改非公开 字段),因此您应该清楚说明(在 PowerShell [Core] v6+ 中您不会遇到该问题,在 $PROFILE
中分配给 [cultureinfo]::CurrentUICulture
就足够了)。与 hack 存在差异的原因是 WinPS 静态 初始化 $PSUICulture
/ $PSCulture
,因此它不知道 hack 执行的更改。我已经在我的答案中添加了一个警告,并且我还在包含 hack 的答案中留下了一个(另一个)评论。以上是关于PowerShell UICulture 与 Windows 设置的主要内容,如果未能解决你的问题,请参考以下文章
Page.UICulture -- 如何检索两个字母的 UICulture 代码?
PowerShell:在Windows 10中为Wi-Fi网络生成QR代码