[tools 3/3] testbot/SetWinLocale: Move the intl.cpl code to Powershell.
Francois Gouget
fgouget at codeweavers.com
Fri Jan 28 11:31:20 CST 2022
Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---
testbot/bin/SetWinLocale | 103 +++++---------------------
testbot/bin/SetWinLocale.ps1 | 136 +++++++++++++++++++++++++++++++++--
2 files changed, 145 insertions(+), 94 deletions(-)
diff --git a/testbot/bin/SetWinLocale b/testbot/bin/SetWinLocale
index b8908e6a0a..2ff8348fb3 100755
--- a/testbot/bin/SetWinLocale
+++ b/testbot/bin/SetWinLocale
@@ -42,7 +42,6 @@ use WineTestBot::TestAgent;
use WineTestBot::Utils;
my $HKCU_USER_PROFILE = "HKCU\\Control Panel\\International\\User Profile";
-my $HKLM_CODE_PAGE = "HKLM\\System\\CurrentControlSet\\Control\\Nls\\CodePage";
#
@@ -53,6 +52,11 @@ my $name0 = $0;
$name0 =~ s+^.*/++;
+sub Info(@)
+{
+ print STDERR "$name0:info: ", @_;
+}
+
sub Warning(@)
{
print STDERR "$name0:warning: ", @_;
@@ -612,19 +616,6 @@ sub RegGetValue($;$)
return $Values->{defined $VName ? $VName : "(Default)"};
}
-sub RegSetValue($$$$)
-{
- my ($Key, $VName, $Type, $Value) = @_;
-
- my $Cmd = ["reg.exe", "add", $Key, "/f"];
- push @$Cmd, (defined $VName ? ("/v", $VName) : ("/ve"));
- $Value = join("\\0", @$Value) if (ref($Value) eq "ARRAY");
- push @$Cmd, "/t" , $Type, "/d", $Value;
-
- my $Ret = $TA->RunAndWait($Cmd, 0, 10);
- FatalError("@$Cmd failed: ", GetRunError($Ret), "\n") if ($Ret);
-}
-
#
# Show the host's locale settings
@@ -823,84 +814,22 @@ $OptKeyboard ||= $OptDefault;
#
-# Generate the intl.cpl configuration
+# Change the Windows locale
#
-my $CopyToSys = $OptSysCopy ? "true" : "false";
-my $CopyToDef = $OptDefCopy ? "true" : "false";
-my @Config = (
- # intl.cpl does not want single quotes on that one line!
- "<gs:GlobalizationServices xmlns:gs=\"urn:longhornGlobalizationUnattend\">",
- " <gs:UserList>",
- " <gs:User UserID='Current' CopySettingsToDefaultUserAcct='$CopyToDef' CopySettingsToSystemAcct='$CopyToSys'/>",
- " </gs:UserList>",
-);
-if (defined $CountryId)
-{
- push @Config, " <gs:LocationPreferences>",
- " <gs:GeoID Value='$CountryId'/>",
- " </gs:LocationPreferences>";
-}
-if ($OptMUI)
-{
- push @Config, " <gs:MUILanguagePreferences>",
- " <gs:MUILanguage Value='$OptMUI'/>",
- " </gs:MUILanguagePreferences>";
-}
-if ($OptSystem)
-{
- push @Config, " <gs:SystemLocale Name='$OptSystem'/>";
-}
-if ($KeyboardIds)
-{
- push @Config, " <gs:InputPreferences>";
- my $Default = " Default='true'";
- foreach my $Id (@$KeyboardIds)
- {
- push @Config, " <gs:InputLanguageID Action='add' ID='$Id'$Default/>";
- $Default = "";
- }
- push @Config, " </gs:InputPreferences>";
-}
-if ($OptLocale)
-{
- push @Config, " <gs:UserLocale>",
- " <gs:Locale Name='$OptLocale' SetAsCurrent='true' ResetAllSettings='true'>",
- " </gs:Locale>",
- " </gs:UserLocale>";
-}
-push @Config, "</gs:GlobalizationServices>";
-
-
-#
-# Change the Windows locale using intl.cpl
-#
-
-Debug(Elapsed($Start), join("\n", " Sending the configuration file\n$name0.xml:", @Config, ""));
-
-if (!$TA->SendFileFromString(join("\r\n", @Config, ""), "$name0.xml", 0))
-{
- FatalError("could not send the configuration file:", $TA->GetLastError(), "\n");
-}
-
my $Cmd = ["powershell.exe", "-ExecutionPolicy", "ByPass", "-File",
- "$name0.ps1", "locales", "$name0.xml"];
-Debug(Elapsed($Start), " Running ", join(" ", @$Cmd), "\n");
-my $Ret = $TA->RunAndWait($Cmd, 0, 120);
+ "$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);
-
-
-#
-# Change the code pages manually
-#
-
-if ($OptUTF8)
+my $Out = $TA->GetFileToString("$name0.out");
+foreach my $Line (split /\n/, $Out || "")
{
- # intl.cpl does not support setting a specific code page
- foreach my $VName ("ACP", "MACCP", "OEMCP")
- {
- RegSetValue($HKLM_CODE_PAGE, $VName, "REG_SZ", "65001");
- }
+ $Line =~ s/\r$//;
+ Info("$Line\n");
}
diff --git a/testbot/bin/SetWinLocale.ps1 b/testbot/bin/SetWinLocale.ps1
index b893755ccb..afb60d6ee5 100644
--- a/testbot/bin/SetWinLocale.ps1
+++ b/testbot/bin/SetWinLocale.ps1
@@ -105,13 +105,65 @@ function ShowSettings()
#
-# Modify the Windows locales settings
+# Modify the Windows locales settings through intl.cpl
#
-function SetLocales($Argv)
+function WriteIntlCplConfig([string]$Locale, [string]$CountryId, [string]$System, [string]$MUI, [string]$KeyboardId, [bool]$SysCopy, [bool]$DefCopy)
{
- $XmlFile = $Argv[1]
- $IntlArg = 'intl.cpl,,/f:"' + $XmlFile + '"'
+ # intl.cpl does not want single quotes on that first line!
+ Write-Output '<gs:GlobalizationServices xmlns:gs="urn:longhornGlobalizationUnattend">'
+
+ Write-Output " <gs:UserList>"
+ $CopyToSys = if ($SysCopy) { "true" } else { "false" }
+ $CopyToDef = if ($DefCopy) { "true" } else { "false" }
+ Write-Output " <gs:User UserID='Current' CopySettingsToDefaultUserAcct='$CopyToDef' CopySettingsToSystemAcct='$CopyToSys'/>"
+ Write-Output " </gs:UserList>"
+
+ if ($CountryId)
+ {
+ Write-Output " <gs:LocationPreferences>"
+ Write-Output " <gs:GeoID Value='$CountryId'/>"
+ Write-Output " </gs:LocationPreferences>"
+ }
+
+ # Takes effect on the next log out + log in.
+ if ($MUI)
+ {
+ # Note that specifying something like en-CA instead of en-GB fails here.
+ # See the Set-WinUILanguageOverride comment above.
+ Write-Output " <gs:MUILanguagePreferences>"
+ Write-Output " <gs:MUILanguage Value='$MUI'/>"
+ Write-Output " </gs:MUILanguagePreferences>"
+ }
+
+ # Takes effect on the next reboot.
+ if ($System)
+ {
+ Write-Output " <gs:SystemLocale Name='$System'/>"
+ }
+
+ # Takes effect on the next log out + log in.
+ if ($KeyboardId)
+ {
+ Write-Output " <gs:InputPreferences>"
+ Write-Output " <gs:InputLanguageID Action='add' ID='$KeyboardId' Default='true'/>"
+ Write-Output " </gs:InputPreferences>"
+ }
+
+ if ($Locale)
+ {
+ Write-Output " <gs:UserLocale>"
+ Write-Output " <gs:Locale Name='$Locale' SetAsCurrent='true' ResetAllSettings='true'>"
+ Write-Output " </gs:Locale>"
+ Write-Output " </gs:UserLocale>"
+ }
+
+ Write-Output "</gs:GlobalizationServices>"
+}
+
+function RunIntlCpl($XmlFilename)
+{
+ $IntlArg = 'intl.cpl,,/f:"' + $XmlFilename + '"'
Write-Output "Running: control.exe $IntlArg"
control.exe $IntlArg
# intl.cpl executes asynchronously which means that:
@@ -121,6 +173,64 @@ function SetLocales($Argv)
# be done after intl.cpl is done to avoid races.
# So 'wait' for intl.cpl to be done by introducing an arbitrary pause.
Start-Sleep 2
+}
+
+
+#
+# Modify the Windows locales through Powershell
+#
+
+function SetCodePages($Value)
+{
+ foreach ($CodePage in $CODE_PAGES)
+ {
+ Set-ItemProperty -Path $HKLM_CODE_PAGE -Name $CodePage -Type String -Value $Value
+ }
+}
+
+
+#
+# The locale-change actions
+#
+
+function GetStringArg($Arg)
+{
+ # Treat '.' as equivalent to an empty string for convenience
+ if ($Arg -ne ".") { $Arg } else { "" }
+}
+
+function ShowIntlConfig($Argv)
+{
+ $Locale = GetStringArg($Argv[1])
+ $CountryId = GetStringArg($Argv[2])
+ $System = GetStringArg($Argv[3])
+ # The UTF8 parameter is irrelevant here
+ $MUI = GetStringArg($Argv[5])
+ $KeyboardId = GetStringArg($Argv[6])
+ $SysCopy = $Argv[7] -ne "false"
+ $DefCopy = $Argv[8] -ne "false"
+
+ WriteIntlCplConfig $Locale $CountryId $System $MUI $KeyboardId $SysCopy $DefCopy
+ exit 0
+}
+
+function SetLocales($Argv)
+{
+ $Locale = GetStringArg($Argv[1])
+ $CountryId = GetStringArg($Argv[2])
+ $System = GetStringArg($Argv[3])
+ $UTF8 = $Argv[4] -eq "true"
+ $MUI = GetStringArg($Argv[5])
+ $KeyboardId = GetStringArg($Argv[6])
+ $SysCopy = $Argv[7] -ne "false"
+ $DefCopy = $Argv[8] -ne "false"
+ $UseIntlCpl = $Argv[9] -eq "true"
+
+ WriteIntlCplConfig $Locale $CountryId $System $MUI $KeyboardId $SysCopy $DefCopy >"$Name0.xml"
+ RunIntlCpl "$Name0.xml"
+ Remove-Item -Path "$Name0.xml"
+
+ if ($UTF8) { SetCodePages(65001) }
exit 0
}
@@ -132,20 +242,32 @@ function SetLocales($Argv)
function ShowUsage()
{
Write-Output "Usage: $Name0 settings"
- Write-Output "or $Name0 locales XMLFILE"
+ 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 -?"
Write-Output ""
Write-Output "Shows or modifies the Windows locales."
Write-Output ""
Write-Output "Where:"
Write-Output " settings Show the current Windows locale settings."
- Write-Output " locales Modifies the locales by passing the $Name0.xml file to intl.cpl."
- Write-Output " XMLFILE The filename of the intl.cpl XML configuration."
+ Write-Output " intlconfig Generates an XML configuration file for intl.cpl."
+ Write-Output " locales Modifies the locales by invoking 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."
+ Write-Output " UTF8 If set to 'true' the code pages will be changed to UTF-8."
+ Write-Output " MUI Is the BCP-47 locale to use for the display language."
+ Write-Output " KEYBOARDID Is the keyboard identifier to set as the default."
+ Write-Output " SYSCOPY If 'true' the locale settings will be copied to the system accounts"
+ 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 " -? Shows this help message."
}
$Action = $args[0]
if ($Action -eq "settings") { ShowSettings }
+if ($Action -eq "intlconfig") { ShowIntlConfig $args }
if ($Action -eq "locales") { SetLocales $args }
$Rc = 0
if ($Action -and $Action -ne "-?" -and $Action -ne "-h" -and $Action -ne "help")
--
2.30.2
More information about the wine-devel
mailing list