PowerShell 多条命令的变化范围 - UICulture

Posted

技术标签:

【中文标题】PowerShell 多条命令的变化范围 - UICulture【英文标题】:PowerShell scope of changes in lines with multiple commands - UICulture 【发布时间】:2020-07-15 07:03:11 【问题描述】:

在我修补与问题Fully change language for the current PowerShell session 的目标相关的 PS 5.1 期间 我观察到一个“奇怪”的行为:

> [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)

(上面的函数来自here)。 将[system.threading.thread]::currentthread. 替换为[cultureinfo]:: 在任何地方都会产生完全相同的结果。

我觉得奇怪的是:

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

    即使Set-Culture 仅在启动新会话后生效,我也可以立即为那个“线程”获得Culture 的更改。 我可能会得出这样的结论。

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

【问题讨论】:

【参考方案1】:

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

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

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

有两种可能的解决方法

使用反射修改 Windows PowerShell 存储启动区域性值的非公共字段 - 请参阅 this answer。

注意:修改非公共字段通常是不明智的,但在这种情况下应该没问题,因为 Windows PowerShell 不会有新的发展;但是,请注意,$PSUICulture / $PSCulture反映解决方法实施的文化 - 请改用 [cultureinfo]::CurrentCulture / [cultureinfo]::CurrentUICulture

或者,在启动 PowerShell 之前更改当前用户的操作系统级别语言/区域设置

以编程方式,

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

您可以使用Set-Culture 更改语言环境文化,反映在[cultureinfo]::CurrentCulture

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


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

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

【讨论】:

以上是关于PowerShell 多条命令的变化范围 - UICulture的主要内容,如果未能解决你的问题,请参考以下文章

每次出现powershell的窗口都太大了,怎么调小一点

用命令行设置powershell 屏幕缓冲区大小

matlab 双y轴绘图能否多条线跟你共用一个y轴?

Powershell的IIS管理小结

C语言switch case后如何执行多条命令

UI半自动化实战-从UI入手,新增多条业务数据