Doing so requires Windows 8+ so keep the intl.cpl code path as a fallback. Support for --sys-copy and --def-copy even requires Windows 11 so keep leveraging intl.cpl to perform the copies. Allow skipping the Powershell APIs by passing --use-intl.
Signed-off-by: Francois Gouget fgouget@codeweavers.com --- The Powershell APIs work a bit differently from intl.cpl: * They automatically set the code pages to UTF-8 for Unicode-only system locales (e.g. Hindi) whereas intl.cpl just fails to modify the system locale in that case. * They automatically adjust the display language locale, for instance from en-CA to en-GB, when again intl.cpl just fails in such a case. Unfortunately these differences make the SetWinLocale behavior a bit inconsistent between these two code paths. --- testbot/bin/SetWinLocale | 21 +++++++++++----- testbot/bin/SetWinLocale.ps1 | 49 ++++++++++++++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 8 deletions(-)
diff --git a/testbot/bin/SetWinLocale b/testbot/bin/SetWinLocale index 81bb2212b1..9f89280ab9 100755 --- a/testbot/bin/SetWinLocale +++ b/testbot/bin/SetWinLocale @@ -316,7 +316,7 @@ sub CheckLocale($$) return undef; }
-my ($OptHostName, $OptShow, $OptSysCopy, $OptDefCopy, $OptReboot); +my ($OptHostName, $OptShow, $OptSysCopy, $OptDefCopy, $OptUseIntl, $OptReboot); my ($OptDefault, $OptLocale, $OptCountry, $OptSystem, $OptUTF8, $OptMUI, $OptKeyboard); while (@ARGV) { @@ -329,6 +329,10 @@ while (@ARGV) { $OptShow = 1; } + elsif ($Arg eq "--use-intl") + { + $OptUseIntl = 1; + } elsif ($Arg eq "--sys-copy") { $OptSysCopy = 1; @@ -457,15 +461,16 @@ if (!defined $Usage) Error("you must specify at least one locale to change\n"); $Usage = 2; } - if (defined $OptReboot) + if ($OptUseIntl or defined $OptReboot) { - Error("--(no-)reboot can only be used when changing a locale\n"); + Error("--use-intl and --(no-)reboot can only be used when changing a locale\n"); $Usage = 2; } } if ($OptShow and ($OptLocale or $OptCountry or $OptSystem or $OptUTF8 or $OptMUI or $OptKeyboard or defined $OptSysCopy or - defined $OptDefCopy or defined $OptReboot)) + defined $OptDefCopy or defined $OptUseIntl or + defined $OptReboot)) { Error("--show and the locale options are mutually incompatible\n"); $Usage = 2; @@ -488,7 +493,7 @@ if (defined $Usage) exit $Usage; } print "Usage: $name0 [options] --show HOSTNAME\n"; - print "or $name0 [options] [--default DEF] [--locale LOC] [--country CTY] [--system SYS] [--utf8] [--mui MUI] [--keyboard KBD] [--no-sys-copy] [--no-def-copy] [--no-reboot] HOSTNAME\n"; + print "or $name0 [options] [--default DEF] [--locale LOC] [--country CTY] [--system SYS] [--utf8] [--mui MUI] [--keyboard KBD] [--no-sys-copy] [--no-def-copy] [--use-intl] [--no-reboot] HOSTNAME\n"; print "\n"; print "Sets the locale of the specified Windows machine.\n"; print "\n"; @@ -563,6 +568,9 @@ if (defined $Usage) print " . Powershell (Windows 11+): Copy-UserInternationalSettingsToSystem -NewUser $True\n"; print " . Intl.cpl: CopySettingsToDefaultUserAcct='true'\n"; print " --no-def-copy Do not copy the current locales to the default user account.\n"; + print " --use-intl Change the locale using the intl.cpl control panel module\n"; + print " instead of Powershell. This option should only be used for\n"; + print " debugging.\n"; print " --no-reboot Do not reboot Windows. Some locale changes will only take\n"; print " effect after the next reboot. This will also prevent working\n"; print " around cases where some locale changes do not stick after a\n"; @@ -835,7 +843,8 @@ sub SetWinLocales($$$$$$$$) "$name0.ps1", "locales", $Locale || ".", $CountryId || ".", $System || ".", $UTF8 ? "true" : "false", $MUI || ".", $KeyboardIds ? $KeyboardIds->[0] : ".", - $SysCopy ? "true" : "false", $DefCopy ? "true" : "false"]; + $SysCopy ? "true" : "false", $DefCopy ? "true" : "false", + $OptUseIntl ? "true" : "false"]; Debug(Elapsed($Start), " Running: ", join(" ", @$Cmd), "\n"); my $Ret = $TA->RunAndWait($Cmd, 0, 30, undef, "$name0.out", "$name0.out"); FatalError("$name0.ps1 locales failed: ", $TA->GetLastError(), "\n") if ($Ret < 0); diff --git a/testbot/bin/SetWinLocale.ps1 b/testbot/bin/SetWinLocale.ps1 index afb60d6ee5..00e9a1af14 100644 --- a/testbot/bin/SetWinLocale.ps1 +++ b/testbot/bin/SetWinLocale.ps1 @@ -188,6 +188,40 @@ function SetCodePages($Value) } }
+$SWC_Success = $True + +function SetWinCulture([string]$Locale, [string]$CountryId, [string]$System, [bool]$UTF8, [string]$MUI, [string]$KeyboardId, [bool]$SysCopy, [bool]$DefCopy) +{ + $Cmd = Get-Command Set-Culture -ErrorAction SilentlyContinue + if ($Cmd -eq $null) { + Write-Output "Set-Culture is not supported" + $global:SWC_Success = $False + return + } + + if ($Locale) { Set-Culture $Locale } + if ($CountryId) { Set-WinHomeLocation $CountryId } + if ($System) { Set-WinSystemLocale $System } + if ($UTF8) { SetCodePages(65001) } + if ($MUI) { Set-WinUILanguageOverride $MUI } + if ($KeyboardId) { Set-WinDefaultInputMethodOverride $KeyboardId } + if ($SysCopy -or $DefCopy) + { + $Cmd = Get-Command Copy-UserInternationalSettingsToSystem -ErrorAction SilentlyContinue + if ($Cmd -ne $null) + { + Copy-UserInternationalSettingsToSystem -WelcomeScreen $SysCopy -NewUser $DefCopy + } + else + { + Write-Output "Copy-UserInternationalSettingsToSystem is not supported. Falling back to intl.cpl for the locales copies." + WriteIntlCplConfig $undef $undef $undef $undef $undef $SysCopy $DefCopy >"$Name0.xml" + RunIntlCpl "$Name0.xml" + Remove-Item -Path "$Name0.xml" + } + } +} +
# # The locale-change actions @@ -226,6 +260,14 @@ function SetLocales($Argv) $DefCopy = $Argv[8] -ne "false" $UseIntlCpl = $Argv[9] -eq "true"
+ if ($UseIntlCpl -eq $False) + { + Write-OutPut "Setting the locales using the Powershell APIs" + SetWinCulture $Locale $CountryId $System $UTF8 $MUI $KeyboardId $SysCopy $DefCopy + if ($SWC_Success -eq $True) { exit 0 } + Write-Output "Falling back to intl.cpl" + } + WriteIntlCplConfig $Locale $CountryId $System $MUI $KeyboardId $SysCopy $DefCopy >"$Name0.xml" RunIntlCpl "$Name0.xml" Remove-Item -Path "$Name0.xml" @@ -243,7 +285,7 @@ function ShowUsage() { Write-Output "Usage: $Name0 settings" Write-Output "or $Name0 intlconfig LOCALE COUNTRYID SYSTEM UTF8 MUI KEYBOARDID SYSCOPY DEFCOPY" - Write-Output "or $Name0 locales LOCALE COUNTRYID SYSTEM UTF8 MUI KEYBOARDID SYSCOPY DEFCOPY" + Write-Output "or $Name0 locales LOCALE COUNTRYID SYSTEM UTF8 MUI KEYBOARDID SYSCOPY DEFCOPY USEINTLCPL" Write-Output "or $Name0 -?" Write-Output "" Write-Output "Shows or modifies the Windows locales." @@ -251,7 +293,8 @@ function ShowUsage() Write-Output "Where:" Write-Output " settings Show the current Windows locale settings." Write-Output " intlconfig Generates an XML configuration file for intl.cpl." - Write-Output " locales Modifies the locales by invoking intl.cpl." + Write-Output " locales Modifies the locales either through the Powershell APIs or" + Write-Output " intl.cpl." Write-Output " LOCALE Is the BCP-47 locale to use for formats, date and time." Write-Output " COUNTRYID Is the numerical country code." Write-Output " SYSTEM Is the BCP-47 locale to use as the system locale." @@ -262,6 +305,8 @@ function ShowUsage() Write-Output " (such as used for the logon screen). This is the default." Write-Output " DEFCOPY If 'true' the locale settings will be copied to the default account" Write-Output " (for new users). This is the default." + Write-Output " USEINTLCPL If 'true' apply the changes using intl.cpl instead of first trying" + Write-Output " the Powershell APIs." Write-Output " -? Shows this help message." }