On Windows 10 21H1 some process typically resets the --locale and --country some time after the login (except when they are changed through the GUI)!!! So wait for the reset to happen and set them again so they are as expected at least until the next reboot :-(
Signed-off-by: Francois Gouget fgouget@codeweavers.com --- This is why UserDefaultLCID is wrong in many of the TestBot VMs :-(
Unfortunately I did not find what's causing the settings to be reset, and what's the difference with changing them through the GUI. At least with this patch GetUserDefaultLCID() and GetUserGeoID() return the expected values in the tests (except when LibvirtTool triggers another reboot before taking the snapshot). --- testbot/bin/SetWinLocale | 92 ++++++++++++++++++++++++++++++++-------- 1 file changed, 74 insertions(+), 18 deletions(-)
diff --git a/testbot/bin/SetWinLocale b/testbot/bin/SetWinLocale index 18cbfc22c5..81bb2212b1 100755 --- a/testbot/bin/SetWinLocale +++ b/testbot/bin/SetWinLocale @@ -41,6 +41,8 @@ use WineTestBot::Log; use WineTestBot::TestAgent; use WineTestBot::Utils;
+my $HKCU_INTERNATIONAL = "HKCU\Control Panel\International"; +my $HKCU_GEO = "HKCU\Control Panel\International\Geo"; my $HKCU_USER_PROFILE = "HKCU\Control Panel\International\User Profile";
@@ -499,12 +501,18 @@ if (defined $Usage) print " ISO 639-1 language code and CC an ISO 3166-1 alpha-2 country\n"; print " code.\n"; print " --locale LOC Specifies the user formats (see --defaults).\n"; + print " . Windows 10 may reset this setting a few seconds after a\n"; + print " the next log in. Thus one should not expect this change to\n"; + print " persist after a reboot.\n"; print " . Windows 10 GUI: Time & language -> Region -> Regional\n"; print " format.\n"; print " . APIs: GetUserDefaultLCID().\n"; print " . Powershell: Set-Culture LOC\n"; print " --country CTY Specifies the location using only the country part of the\n"; print " Windows locale (see --defaults).\n"; + print " . Windows 10 may reset this setting a few seconds after a\n"; + print " the next log in. Thus one should not expect this change to\n"; + print " persist after a reboot.\n"; print " . Windows 10 GUI: Time & language -> Region -> Country.\n"; print " . APIs: GetUserGeoID().\n"; print " . Powershell: Set-WinHomeLocation -GeoId CTY-ID\n"; @@ -555,9 +563,10 @@ 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 " --no-reboot Do not reboot Windows. Some locale changes only take effect\n"; - print " after a reboot so 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"; + print " reboot. So this should only be used for debugging.\n"; print " --debug Show more detailed information about progress.\n"; print " --help Shows this usage message.\n"; exit 0; @@ -713,9 +722,10 @@ sub ShowWinSettings($) print "InputMethod (--keyboard) = ", Value2Str($Settings->{DefInputMethod}), "\n"; }
+my $InitialSettings = GetWinSettings(); if ($OptShow) { - ShowWinSettings(GetWinSettings()); + ShowWinSettings($InitialSettings); Cleanup(); exit(0); } @@ -814,24 +824,32 @@ $OptKeyboard ||= $OptDefault;
# -# Change the Windows locale +# Helper to change the Windows locales #
-my $Cmd = ["powershell.exe", "-ExecutionPolicy", "ByPass", "-File", - "$name0.ps1", "locales", $OptLocale || ".", $CountryId || ".", - $OptSystem || ".", $OptUTF8 ? "true" : "false", $OptMUI || ".", - $KeyboardIds ? $KeyboardIds->[0] : ".", - $OptSysCopy ? "true" : "false", $OptDefCopy ? "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); -my $Out = $TA->GetFileToString("$name0.out"); -foreach my $Line (split /\n/, $Out || "") +sub SetWinLocales($$$$$$$$) { - $Line =~ s/\r$//; - Info("$Line\n"); + my ($SysCopy, $DefCopy, $Locale, $CountryId, $System, $UTF8, $MUI, $KeyboardIds) = @_; + + my $Cmd = ["powershell.exe", "-ExecutionPolicy", "ByPass", "-File", + "$name0.ps1", "locales", $Locale || ".", $CountryId || ".", + $System || ".", $UTF8 ? "true" : "false", $MUI || ".", + $KeyboardIds ? $KeyboardIds->[0] : ".", + $SysCopy ? "true" : "false", $DefCopy ? "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); + my $Out = $TA->GetFileToString("$name0.out"); + foreach my $Line (split /\n/, $Out || "") + { + $Line =~ s/\r$//; + Info("$Line\n"); + } }
+SetWinLocales($OptSysCopy, $OptDefCopy, $OptLocale, $CountryId, + $OptSystem, $OptUTF8, $OptMUI, $KeyboardIds); +
# # Reboot to finalize the changes @@ -839,7 +857,7 @@ foreach my $Line (split /\n/, $Out || "")
if ($OptReboot) { - $Cmd = ["shutdown.exe", "/r", "/t", "0"]; + my $Cmd = ["shutdown.exe", "/r", "/t", "0"]; Debug(Elapsed($Start), " Rebooting: ", join(" ", @$Cmd), "\n"); $TA->Run($Cmd, 0); # Note that we cannot wait for this command since it reboots Windows @@ -853,6 +871,44 @@ if ($OptReboot) { FatalError("could not reconnect to $OptHostName after the reboot: ", $TA->GetLastError(), "\n"); } + + # Skip this check on pre-Windows 10 versions, i.e. those that don't have + # 'CountryName' and if the settings were not changed in the first place. + if ($InitialSettings->{CountryName} and + (($OptLocale and $InitialSettings->{Locale} ne $OptLocale) or + ($OptCountry and $InitialSettings->{Country} ne $CountryId))) + { + # On Windows 10 21H1 some process typically resets the --locale and + # --country some time after the login!!! + # This also happens when making the change through the Powershell's + # Set-Culture and Set-WinHomeLocation calls, but not when manually going + # through the GUI. + # So wait for the reset to happen and re-set them :-( + my $Expected = $OptLocale ? "--locale $OptLocale" : ""; + $Expected .= !$OptCountry ? "" : (($Expected ? " and " : "") . ("--country $OptCountry")); + Debug(Elapsed($Start), " Expecting $Expected to get reverted\n"); + foreach (1..30) + { + my $Reverted; + if ($OptCountry) + { + my $Nation = RegGetValue($HKCU_GEO, "Nation"); + $Reverted = "--country $Nation" if ($Nation ne $CountryId); + } + else + { + my $LocaleName = RegGetValue($HKCU_INTERNATIONAL, "LocaleName"); + $Reverted = "--locale $LocaleName" if ($LocaleName ne $OptLocale); + } + if ($Reverted) + { + Warning("$Expected got reverted to $Reverted. Setting them again but this will not stick across reboots\n"); + SetWinLocales(undef, undef, $OptLocale, $CountryId, undef, undef, undef, undef); + last; + } + sleep(2); + } + } }