Лечим раскладку клавиатуры

В одном из последних (весенних ещё) обширных обновлений винда как обычно испортило мне5 раскладку.

У меня такая раскладка:
ENG English (United States)/ US keyboard – основная
РУС Russian Russian keyboard.

Английская основная, т.к. я в основном занимаюсь программированием, а все языки программирования, кроме Рапиры, требуют латинской раскладки.

Переклчюаюсь я по Ctrl+Shift.

Итак, как я уже сказал, испортили мне опять раскладку, поставили en-GB вместе с en-US, удалили раскладку РУС.

Так вот, раньше в Language Preferences я мог быстро удалить ненужные раскладки, добавить нужные и выбрать раскладку по умолчанию.
Теперь же, после последнего обнолвения – нет. Не могу удалить EN-GB, хотя она не назначена как дефолтная.
Кнопка “Remove” у неё почему-то не активна во всех случаях.

Искал я инфо в интернете, пробовал разные варианты, в том числеи с редактированием реестра инастройкой различных прав доступа,
перезапускал раз десять систему, что делаю довольно редко, т.к. во время отдыха кладуего в сон – ничего не помогло.

Помог только один вариант, которые я нашёл в конце постов на каком-то форуме, и этот вариант предлагал использование Windows Power Shell.
Выглядит дико, признаю, но это факт. Как обычным пользователям, не знакомым с оболочками и программированием исправить себе раскладку клавиатуры, я не знаю!

Итак, сценарий исправления таков:

1. Открываем Power Shell с администраторскими правами.
2. Смотрим текущие раскладки:
PS C:\WINDOWS\system32> Get-WinUserLanguageList

LanguageTag : en-US
Autonym : English (United States)
EnglishName : English
LocalizedName : English (United States)
ScriptName : Latin script
InputMethodTips : {0409:00000409}
Spellchecking : True
Handwriting : False

LanguageTag : en-AU
Autonym : English (Australia)
EnglishName : English
LocalizedName : English (Australia)
ScriptName : Latin script
InputMethodTips : {0C09:00001809}
Spellchecking : True
Handwriting : False

LanguageTag : ru
Autonym : русский
EnglishName : Russian
LocalizedName : Russian
ScriptName : Cyrillic
InputMethodTips : {0419:00000419}
Spellchecking : True
Handwriting : False

LanguageTag : en-GB
Autonym : English (United Kingdom)
EnglishName : English
LocalizedName : English (United Kingdom)
ScriptName : Latin script
InputMethodTips : {0809:00000809}
Spellchecking : True
Handwriting : False

Тут видны 4 раскладки, это я экспериментировал, пытаясь добавлять/удалять и переназначать дефолтные раскладки.

Итак, чтобы устновить одну только раскладку, удалив все осталдьные, выполняем такую команду:
PS C:\WINDOWS\system32> Set-WinUserLanguageList -LanguageList en-US -Force
и смотрим, что получилось:
PS C:\WINDOWS\system32> Get-WinUserLanguageList

LanguageTag : en-US
Autonym : English (United States)
EnglishName : English
LocalizedName : English (United States)
ScriptName : Latin script
InputMethodTips : {0409:00000409}
Spellchecking : True
Handwriting : False

ОК, но как нам теперь доавить русскую раскладку? Не существует метода типа Add-WinUserLanguage, естьт только команды Set-/Get-WinUserLanguageList.

Для формирования нужной раскладки нам надо создать оъект с нужными раскладками и передать его в качестве парметра Set-WinUserLanguageList.

Так как я не особо шарю в PowerShell, больше в линуксовых оболчках работаю, то делаю все моим любимым методом проб и ошибок, пытаясь нарыть нужную инфо через Гугл.

Вот мои действия, которые в итоге привели к успеху, я сейчас имю 2 нужные мне раскладки, описанные в начале поста, и они нормально функционируют, большего мне не нужно!
Итак, удаляем все раскладки, что можно, помня, что EN-GB не удаляется совсем, неважно, дефолтная она или нет, т.к. кнопка “Remove” по загадочным причинам не активна совсем.
Доабвляем EN-US, делаем её дефолтной и переставляем на первое место, потом добавляем раскладку РУС.

Теперь запускам Power Shell с административными привилегиями и делаем так:

PS C:\Users\Andrey> $list = Get-WinUserLanguageList
PS C:\Users\Andrey> $list
 
 
LanguageTag     : en-US
Autonym         : English (United States)
EnglishName     : English
LocalizedName   : English (United States)
ScriptName      : Latin script
InputMethodTips : {0409:00000409}
Spellchecking   : True
Handwriting     : False
 
LanguageTag     : en-GB
Autonym         : English (United Kingdom)
EnglishName     : English
LocalizedName   : English (United Kingdom)
ScriptName      : Latin script
InputMethodTips : {0809:00000809}
Spellchecking   : True
Handwriting     : False
 
LanguageTag     : ru
Autonym         : русский
EnglishName     : Russian
LocalizedName   : Russian
ScriptName      : Cyrillic
InputMethodTips : {0419:00000419}
Spellchecking   : True
Handwriting     : False
 
 
PS C:\Users\Andrey> $x = ($list[0], $list[2])
PS C:\Users\Andrey> $x
 
 
LanguageTag     : en-US
Autonym         : English (United States)
EnglishName     : English
LocalizedName   : English (United States)
ScriptName      : Latin script
InputMethodTips : {0409:00000409}
Spellchecking   : True
Handwriting     : False
 
LanguageTag     : ru
Autonym         : русский
EnglishName     : Russian
LocalizedName   : Russian
ScriptName      : Cyrillic
InputMethodTips : {0419:00000419}
Spellchecking   : True
Handwriting     : False
 
 
PS C:\Users\Andrey> Set-WinUserLanguageList $x
 
Confirm
Continue with this operation?
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"): y

Всё, теперь у нас только 2 раскладки, EN-US и РУС:

PS C:\Users\Andrey> $list = Get-WinUserLanguageList
PS C:\Users\Andrey> $list
 
 
LanguageTag     : en-US
Autonym         : English (United States)
EnglishName     : English
LocalizedName   : English (United States)
ScriptName      : Latin script
InputMethodTips : {0409:00000409}
Spellchecking   : True
Handwriting     : False
 
LanguageTag     : ru
Autonym         : русский
EnglishName     : Russian
LocalizedName   : Russian
ScriptName      : Cyrillic
InputMethodTips : {0419:00000419}
Spellchecking   : True
Handwriting     : False

В этом можно также убедиться, щёлкнув на раскладку в трее справа.

Информация, которую я использовал для поиска нужного варианта:
************************************************************************************************

Удалять/добавлять нужные раскладки:
$list = Get-WinUserLanguageList

Возвращает массив с 2 объектами – пример для Английской и Литовской раскладок:

$list[0]:
LanguageTag : en-US
Autonym : English (United States)
EnglishName : English
LocalizedName : English (United States)
ScriptName : Latin script
InputMethodTips : {0409:00000409}
Spellchecking : True
Handwriting : False

$list[1]:
LanguageTag : lt
Autonym : lietuvių
EnglishName : Lithuanian
LocalizedName : Lithuanian
ScriptName : Latin script
InputMethodTips : {0427:00010427}
Spellchecking : True
Handwriting : False

Теперь мы можем установить одну расклдаку из массива так:
Set-WinUserLanguageList $($list[0])

Если же English и Lithuanian раскладки под индексом 0 и 1 в массиве, мы можем сделать так, чтобы добавить только две эти раскладки в системе:
$x = ($list[0], $list[1])
Set-WinUserLanguageList $x

********************************
Работаем с массивами в Power Shell

$x.RemoveAt(1) – не работает?
$x.remove(($x|where-object languagetag -eq ‘ru’)) – тоже не рбаотает?

Оба этих метода выдют одну ошибку:
************************************************************************************************
Exception calling “RemoveAt” with “1” argument(s): “Collection was of a fixed size.”
At line:1 char:1
+ $x.RemoveAt(0)
+ ~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : NotSupportedException
************************************************************************************************
Ага попробуем с такого примера: https://stackoverflow.com/questions/40274422/remove-a-row-from-a-powershell-array-collection-hashtable

Оказывается, массивы неизменянемы в PowerShell, и мы не можем удалять/добавлять к ним элементы. Но мы можем выбрать изтаких варинатов:

a) Создать новый массив, отфильтровав не нужные нам элементы (например применяя -ne)
$data = $data | ? {$_.Server -ne “Total”}

b) Выбрать всё до последнего элемента по индексу:
$data = $data[0..($data.Count-2)]

c) Преобразовать массив к [System.Collections.ArrayList], который изменяем, и удалить элементы из него:
$data = [System.Collections.ArrayList]$data
$data.RemoveAt($data.Count-1)

в нашем случае:
$x = [System.Collections.ArrayList]$x
$x.RemoveAt(1)
$x.GetType()
$x

LanguageTag : en-US
Autonym : English (United States)
EnglishName : English
LocalizedName : English (United States)
ScriptName : Latin script
InputMethodTips : {0409:00000409}
Spellchecking : True
Handwriting : False

************************************************************************************************
************************************************************************************************

You can easily change current input language via .NET class, like this:

Add-Type -AssemblyName ‘System.Windows.Forms’
[System.Windows.Forms.InputLanguage]::CurrentInputLanguage = [System.Windows.Forms.InputLanguage]::InstalledInputLanguages | ? { $_.Culture -eq ‘ru-RU’ }

************************************************************************************************