我编写了一些使用系统(powershell)命令输出的软件,但没有预见到除英语之外的其他语言的输出会有所不同。
有没有办法暂时将 Powershell 中的语言更改为英语,仅用于单个 powershell 会话?
(a)对于诸如 之类的外部程序netstat.exe,遗憾的是没有办法(据我所知)在会话中更改 UI 语言:
在 Windows Server 2012 / Windows 8 及更高版本上,该Set-WinUILanguageOverridecmdlet允许您(持续)更改当前用户的系统范围的 UI 语言,但这仅在未来的登录会话中生效- 即注销并重新登录或需要重启。
顺便说一句:在 Windows Server 2012 / Windows 8 及更高版本上,也有Set-Culturecmdlet,但其目的不是更改UI文化(显示语言),而只是特定于文化的设置,例如日期、数字和货币格式. 它也为当前用户持久地更改设置,但只需要一个新的会话(进程)才能使更改生效。
(二)对于PowerShell的命令和.NET类型,存在是一个会议期间(非持久性)溶液-假设的命令是培养感知,并配备了本地化字符串:
设置[cultureinfo]::CurrentUICulture(暂时)为所需的文化名称(用于[cultureinfo]::GetCultures('SpecificCultures')查看所有预定义的);例如, [cultureinfo]::CurrentUICulture = 'en-US'
[cultureinfo]::CurrentCulture(注意缺少的UI部分),这决定了特定于文化的数字、日期、...格式。[System.Threading.Thread]::CurrentThread;例如,[System.Threading.Thread]::CurrentThread.CurrentUICulture = 'en-US'请参阅底部部分,了解包装此功能以在不同文化暂时生效时执行代码的辅助函数Use-Culture。
注意事项:
从 v7.0 开始, PowerShell [Core]本身还没有本地化;此 GitHub 问题正在跟踪进度;但是,下面的解决方案确实适用于附带本地化消息和帮助内容的第三方模块。
由于在错误的Windows PowerShell(PowerShell的[核心] V6 +是不受到影响),在会话的变化[cultureinfo]::CurrentUICulture和[cultureinfo]::CurrentCulture被自动复位在命令提示,每当执行一个命令完成; 但是,对于给定的脚本,更改对整个脚本及其被调用者仍然有效 - 请参阅此答案。
退一步:
我编写了一些使用系统(powershell)命令输出的软件,但没有预见到除英语之外的其他语言的输出会有所不同。
这正是为什么通常值得寻找PowerShell 本地解决方案而不是调用外部程序的原因:
例如,PowerShell 命令不必像 那样解析(可能是本地化的)文本,而是netstat.exe返回可以以独立于文化的方式稳健访问其属性的对象。
具体来说,Mathias R. Jessen建议将其Get-NetTCPConnection视为 PowerShell 的替代方案netstat.exe(在 Windows Server 2012 / Windows 8 及更高版本上可用)。
为了帮助 (b),下面是辅助函数Use-Culture,您可以使用它{ ... }在给定 (UI) 文化的上下文中执行给定的脚本块 ( ):
# Windows PowerShell: emit an error message in *French* (culture 'fr-FR')
# Note: Does not yet work as of PowerShell [Core] 7.0
PS> Use-Culture fr-FR { try { 1/0 } catch { "Localized message: $_" } }
Localized message: Tentative de division par zéro.
Run Code Online (Sandbox Code Playgroud)
请注意,文化变化 - 对于文化和 UI 文化 - 都是命令范围的;也就是说,命令完成后,先前的设置将再次生效。
Use-Culture的源代码:注意:代码改编自这篇著名的博文。
# Runs a script block in the context of the specified culture, without changing
# the session's culture persistently.
# Handy for quickly testing the behavior of a command in the context of a different culture.
# Example:
# Use-Culture fr-FR { Get-Date }
function Use-Culture
{
param(
[Parameter(Mandatory)] [cultureinfo] $Culture,
[Parameter(Mandatory)] [scriptblock] $ScriptBlock
)
# Note: In Windows 10, a culture-info object can be created from *any* string.
# However, an identifier that does't refer to a *predefined* culture is
# reflected in .LCID containing 4096 (0x1000)
if ($Culture.LCID -eq 4096) { Throw "Unrecognized culture: $($Culture.DisplayName)" }
# Save the current culture / UI culture values.
$PrevCultures = [Threading.Thread]::CurrentThread.CurrentCulture, [Threading.Thread]::CurrentThread.CurrentUICulture
try {
# (Temporarily) set the culture and UI culture for the current thread.
[Threading.Thread]::CurrentThread.CurrentCulture = [Threading.Thread]::CurrentThread.CurrentUICulture = $Culture
# Now invoke the given code.
& $ScriptBlock
}
finally {
# Restore the previous culture / UI culture values.
[Threading.Thread]::CurrentThread.CurrentCulture = $PrevCultures[0]
[Threading.Thread]::CurrentThread.CurrentUICulture = $PrevCultures[1]
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5507 次 |
| 最近记录: |