Signed-off-by: Francois Gouget fgouget@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")