Skip to content

Instantly share code, notes, and snippets.

@ruxo
Last active February 9, 2023 23:16
Show Gist options
  • Select an option

  • Save ruxo/8679254cff13fcb124bf2fe73ecac697 to your computer and use it in GitHub Desktop.

Select an option

Save ruxo/8679254cff13fcb124bf2fe73ecac697 to your computer and use it in GitHub Desktop.
For Windows 10 & 11: Remove unwanted UK keyboard from Windows glitch!
open Microsoft.Win32
module Keyboard =
let ThaiKeyboard = ["0000041e"]
let USKeyboard = ["00000409"]
let UKKeyboards = ["00000809"; "d0010409" ]
let OurDesiredKeyboards = [ThaiKeyboard; USKeyboard] |> List.collect id
let WellknownKeyboards = [ThaiKeyboard; USKeyboard; UKKeyboards] |> List.collect id
let isUK v = UKKeyboards |> List.contains v
let isPreferred v = OurDesiredKeyboards |> List.contains v
module RegistryEx =
type RegistryKeyPair = (struct (string * obj))
let regKeyPairOf (r: RegistryKey) name =
match r.GetValue(name) with
| null -> failwithf "Invalid key name %s" name
| v -> name, v
let getKeyPairs (r: RegistryKey) :RegistryKeyPair seq =
r.GetValueNames() |> Seq.map (fun name -> struct (name, r.GetValue(name)))
type RegistryKey with
member private this.openNext(name: string) =
use dispose = this
let next = this.OpenSubKey(name)
next
member private this.openByNames(names: string seq) =
names |> Seq.fold (fun (current: RegistryKey) name -> current.openNext name) this
member this.openRead(path: string) = this.openByNames <| path.Split('/')
member this.openForWrite(path: string) =
let parts = path.Split('/','\\')
use parent = this.openByNames(seq { for i in 0..parts.Length-2 -> parts.[i] })
parent.OpenSubKey(parts |> Array.last, writable=true)
let fstv struct (a,_) = a
let sndv struct (_,b) = b
let fixUserSettings() =
printfn "Check in User Settings..."
use preloads = Registry.CurrentUser.openForWrite("Keyboard Layout/Preload")
let preloadKeyboards = preloads |> RegistryEx.getKeyPairs |> Seq.map (fun struct (k,v) -> struct (k, v :?> string))
printf "Remove UK keyboard from preload..."
let uk_keyboard_entry = preloadKeyboards
|> Seq.filter (sndv >> Keyboard.isUK)
|> Seq.tryHead
match uk_keyboard_entry with
| Some (name, _) -> preloads.DeleteValue(name)
| None -> let unknowns = preloadKeyboards
|> Seq.filter (sndv >> (not << Keyboard.isUK))
|> Seq.filter (sndv >> (not << Keyboard.isPreferred))
|> Seq.toList
if unknowns.IsEmpty
then printfn "UK keyboard not found"
else printfn "UK keyboard not found, some strange keyboards detected: %A" unknowns
printfn "End: Check in User Settings\n"
let checkProfileInDefaultUsers() =
printfn "Check keyboard in default user..."
let removeUKKeyboards target =
let items = target |> RegistryEx.getKeyPairs
let isItemUKKeyboard (s: string) =
let parts = s.Split(':')
if parts.Length > 1
then parts[1] |> Keyboard.isUK
else false
let ukKeys = items |> Seq.map fstv |> Seq.filter isItemUKKeyboard |> List.ofSeq
if ukKeys.Length > 0 then
printfn "Found UK keyboard! %A" ukKeys
ukKeys |> Seq.iter target.DeleteValue
printfn "UK keyboars removed!"
else
printfn "No UK keyboards found"
use defaultUSProfile = Registry.Users.openForWrite(".DEFAULT\Control Panel\International\User Profile\en-US")
use defaultUSProfileBackup = Registry.Users.openForWrite(".DEFAULT\Control Panel\International\User Profile System Backup\en-US")
removeUKKeyboards defaultUSProfile
removeUKKeyboards defaultUSProfileBackup
printfn "End: Check keyboard in default user..."
fixUserSettings()
checkProfileInDefaultUsers()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment