Reputation: 129
I'm building a code to fix keyboard layout situation on windows 10. With automated solution, I decided to use powershell. But the problem is that I'm pretty new in it and face certain problems. I managed to dig a script to change keyboard layouts, however it changes only to one language. As I try to create array with 2 languages:
$langlist=$lang_en,$lang_ru
set-winuserlanguagelist $langlist
It simply returns me next error:
Set-WinUserLanguageList : Cannot convert 'Microsoft.InternationalSettings.Commands.WinUserLanguage' to the type
'Microsoft.InternationalSettings.Commands.WinUserLanguage' required by parameter 'LanguageList'. Specified method is
not supported.
At line:1 char:25
+ set-winuserlanguagelist $langlist
+ ~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-WinUserLanguageList], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.InternationalSettings.Commands.SetWinUserLanguageListCommand
When I tried to use next command: $test = Get-WinUserLanguageList
, the command works well with set-winuserlanguagelist
.
The full script:
$keys='0809:00020409', '0419:00000419'
$lang_en=new-winuserlanguagelist en-gb
$lang_en[0].inputmethodtips.clear()
$lang_en[0].inputmethodtips.add($keys[0])
$lang_ru=new-winuserlanguagelist ru
$lang_ru[0].inputmethodtips.clear()
$lang_ru[0].inputmethodtips.add($keys[1])
$langlist=$lang_en,$lang_ru
set-winuserlanguagelist $langlist
Upvotes: 3
Views: 3403
Reputation: 2320
The Set-WinUserLanguageList cmdlet has evolved (at lease since Win 20H1) and the syntax is now very straightforward:
Set-WinUserLanguageList -LanguageList 'fr-FR','en-US','en-GB'
If you want to add additional languages to the existing ones, you can use this code snippet:
$CurrentLanguageList = Get-WinUserLanguageList
$NewLanguageList = [System.Collections.ArrayList]::new()
foreach($Language in $CurrentLanguageList.LanguageTag){
$NewLanguageList.Add($Language) | Out-Null
}
#Adding new languages here
$NewLanguageList.Add('de-DE') | Out-Null
$NewLanguageList.Add('ru-RU') | Out-Null
Set-WinUserLanguageList -LanguageList $NewLanguageList
Upvotes: 0
Reputation: 438073
The problem is that you're using New-WinUserLanguageList
twice, with each call returning a list, so that $langlist = $lang_en, $lang_ru
mistakenly created an array of (single-item) lists rather than a single list with two items, which caused the (nonsensically-sounding) type-mismatch error you saw.
Very awkwardly, however, cmdlet New-WinUserLanguageList
only allows you to specify one language, even though it returns a list type ([Collections.Generic.List[Microsoft.InternationalSettings.Commands.WinUserLanguage]]
).
That is, the following should work, but doesn't:
# Try to create the list with *2* entries
$langlist = New-WinUserLanguageList en-gb, ru # !! Doesn't work, parameter type is [string]
Instead, you have to initialize with 1 language and then add additional ones later, using the .Add()
method:
# Create the list with initially just 'en-gb'...
$langlist = New-WinUserLanguageList en-gb
# ... and then add the other language, 'ru'
# Because the list is strongly typed, it is sufficient to pass the language
# identifier, which implicitly creates a new
# [Microsoft.InternationalSettings.Commands.WinUserLanguage] instance.
$langlist.Add('ru')
# Now you can modify the properties of $langlist[0] (en-gb)
# and $langlist[1] (ru)
# ...
# ... and pass the list of modified languages to Set-WinUserLanguageList:
Set-WinUserLanguageList $langlist
Alternatively, to avoid the .Add()
call, you could have used:
$langlist = (New-WinUserLanguageList en-gb)[0], (New-WinUserLanguageList ru)[0]
Even though $langlist
is then technically an array (a [System.Object[]]
instance whose elements are of type Microsoft.InternationalSettings.Commands.WinUserLanguage
), passing it to Set-WinUserLanguageList
works, because it is implicitly converted to the required list type.
Upvotes: 2
Reputation: 30123
Please check the following commented code snippets:
PS D:\PShell> ### Type mismatch
$langlist=$lang_en,$lang_ru
### Note the difference in type:
$langlist.gettype().Name ### Object[]
(Get-WinUserLanguageList).gettype().Name ### List`1
Object[] List`1
PS D:\PShell> ### Use the following:
$langlist = Get-WinUserLanguageList
$langlist.Clear()
$langlist.Add($lang_en[0])
$langlist.Add($lang_ru[0])
$langlist.gettype().Name ### List`1
List`1
PS D:\PShell> <### The next cmdlet should work now:
set-winuserlanguagelist $langlist
<##>
Upvotes: 2