I'm a student building a Windows automation project that detects connected USB keyboards by VID/PID and switches the active keyboard layout—for example, selecting an ANSI layout when a particular mechanical keyboard is plugged in. Changing HKCU:Keyboard LayoutPreload works eventually, but Windows may not apply it until the user logs out or the shell restarts. As a workaround, I used PowerShell P/Invoke through Add-Type to inspect the foreground window's keyboard layout and simulate Win+Space enough times to reach the desired layout. This provides immediate visual feedback, but it relies on keybd_event and timed delays. The script is part of a larger Electron and React application called WindowsFlow. Is there a cleaner Win32 or PowerShell API for changing the active layout directly, without simulating keyboard input or waiting for registry changes?
3 Answers
Set-WinDefaultInputMethodOverride may be worth testing. It is designed to set the default input method without manually editing the registry. However, a default-input override is not always the same as changing the layout that is active in the current foreground application, so it may not provide the instant behavior you want. You’ll need to verify it with multiple running applications and separate input profiles.
Be careful with the distinction between changing the user’s preferred/default input method and activating a layout immediately. The former affects future sessions or defaults, while the latter may require an application-specific request or a thread-level Win32 call. Also, consider documenting the code in standard PowerShell code blocks and putting the native declarations in a reusable module so the project is easier to maintain.
Simulating Win+Space is fairly fragile. It assumes the user’s shortcut configuration, depends on timing, and can mix with real input or send keystrokes to the wrong window if focus changes. It may also look suspicious to security software. Since you’re already using P/Invoke, use the APIs intended for layout changes instead, such as LoadKeyboardLayout and ActivateKeyboardLayout, or send WM_INPUTLANGCHANGEREQUEST to the foreground window when appropriate. A PowerShell module or compiled cmdlet would also be cleaner than calling Add-Type repeatedly, since the compiled type remains available for the lifetime of the session. For the USB-triggering side, WMI or system event subscriptions can be used instead of polling.

That makes sense. I originally used simulated input as a quick workaround for the registry delay, but focus changes and mixed input were my main concerns too. I’ll replace it with a direct Win32 layout call and package the native code as a proper module. I’ll also check whether an existing PowerShell command already handles the active-layout change.