1

在我修补与问题目标有关的 PS 5.1完全更改当前 PowerShell 会话的语言期间, 我观察到一个“奇怪”的行为:

> [system.threading.thread]::currentthread.currentculture ; [system.threading.thread]::currentthread.currentuiculture ;
LCID             Name             DisplayName
----             ----             -----------
1033             en-US            English (United States)
1033             en-US            English (United States)
> function Set-CultureWin([System.Globalization.CultureInfo] $culture) { [System.Threading.Thread]::CurrentThread.CurrentUICulture = $culture ; [System.Threading.Thread]::CurrentThread.CurrentCulture = $culture } ; Set-CultureWin es-ES ; [system.threading.thread]::currentthread.currentculture ; [system.threading.thread]::currentthread.currentuiculture ;
LCID             Name             DisplayName
----             ----             -----------
3082             es-ES            Español (España)
3082             es-ES            Español (España)
> [system.threading.thread]::currentthread.currentculture ; [system.threading.thread]::currentthread.currentuiculture ;
LCID             Name             DisplayName
----             ----             -----------
1033             en-US            English (United States)
1033             en-US            English (United States)

(上面的函数是从这里获得的)。[system.threading.thread]::currentthread.用任何地方替换[cultureinfo]::产生完全相同的结果。

我发现奇怪的是:

  1. 我得出结论,“线程”(当前线程)的边界似乎是执行命令行。
    尽管如此,这里它被引用为“会话范围(非持久)解决方案”(响应其 OP Temporarily change powershell language to English?)。该答案甚至发布了一个包装函数来限制对执行命令的更改范围。
    该信息显然反对这一点,它指出“[Threading.Thread]::CurrentThread.CurrentUICulture仅影响当前的单线”(与我的结论一致)。

  2. Culture即使Set-Culture仅在启动新会话后生效 ,我也可以立即更改那个“线程”。
    我可能会得出结论,这就是它的工作原理。

这两点如何合理化? (我欢迎权威文档)。

4

1 回答 1

1

由于Windows PowerShell [1]中的一个错误(PowerShell [Core] v6+不受影响,每当命令完成执行时,在命令提示符下的会话更改自动重置启动时[2]的值。[cultureinfo]::CurrentUICulture[cultureinfo]::CurrentCulture

不幸的是,尝试修改文化$PROFILE同样受到影响。

但是,对于给定的脚本,脚本内文化更改对整个脚本及其被调用者(在主线程上)仍然有效 - 请参阅此答案

有两种可能的解决方法

  • 使用反射来修改 Windows PowerShell 存储启动区域性值的非公共字段- 请参阅此答案

    • 注意:修改非公共字段通常是不明智的,但在这种情况下应该没问题,因为 Windows PowerShell 不会有新的发展;但是,请注意$PSUICulture/$PSCulture不会反映解决方法所实施的文化 - 请改用[cultureinfo]::CurrentCulture/ [cultureinfo]::CurrentUICulture
  • 或者,在启动 PowerShell之前更改当前用户的操作系统级语言/区域设置

    • 以编程方式,

      • 你可以改变当前用户的显示语言UI文化,体现在[cultureinfo]::CurrentUICultureSet-WinUILanguageOverride

      • 您可以更改语言环境文化,反映在[cultureinfo]::CurrentCultureSet-Culture

      • 请注意,这两个命令至少需要 Windows 8 / Windows Server 2012 R2 并且Set-WinUILanguageOverride需要注销重新启动才能生效,而Set-Culture更改仅在以后的会话中生效(但不需要注销/重新启动)。


[1] 没有我知道的官方错误报告,但以下因素导致我将 Windows PowerShell 的行为归类为错误:该行为违反直觉,除了通过hack之外无法避免,并且已在 PowerShell 中更正[核心] v6+。此外,PowerShell 团队的一位核心成员在这个 GitHub 问题中这样说:“我忘记了确切的细节,但是由于我不明白的原因,当前的文化被重置了。”

[2] PowerShell进程启动时的值,由用户的操作系统级显示语言和区域设置(区域格式)确定。

于 2020-07-16T16:02:57.053 回答