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 Set-UICulture cmdlet,但在 Windows 8 / Windows Server 2012 R2 及更高版本中,您可以使用 Set-WinUILanguageOverride cmdlet。 请注意,与目标文化相关的语言的语言包必须是系统自带的,或者必须事先下载。

重要提示:在您注销并重新登录或重新启动之前,更改不会生效。

文化,又名区域格式(语言环境)

使用Set-Culture cmdlet,在 Windows 8 / Windows Server 2012 R2 及更高版本中可用。

重要提示:更改仅在未来 PowerShell 会话中生效,但不需要注销/重新启动。

仅限会话中更改

重要提示:此类更改仅适用于基于.NET的应用程序。因此,从更改了区域性的 PowerShell 会话中调用非 .NET 控制台应用程序对该控制台应用程序没有影响。但是,更改确实对 PowerShell cmdlet、脚本和函数的调用生效。即使更改的范围在技术上仅限于 当前线程,PowerShell 也会将更改传播到在 new 线程(Start-ThreadJobForEach-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。

警告:Windows PowerShell 静态地初始化$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 设置的主要内容,如果未能解决你的问题,请参考以下文章

完全更改当前 PowerShell 会话的语言(包括文化)

Page.UICulture -- 如何检索两个字母的 UICulture 代码?

PowerShell:在Windows 10中为Wi-Fi网络生成QR代码

默认 Culture 和 UICulture 是如何确定的?

静态 UICulture 设置和隐式本地化的问题

为 Web 应用程序中的子文件夹设置 UICulture