[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