# A script to toggle the Touch Keyboard of Windows 11, # compatible with both Windows PowerShell and PowerShell 7. # Based on code by @torvin (https://stackoverflow.com/users/332528/torvin): https://stackoverflow.com/a/40921638 # Based on code by @Andrea S. (https://stackoverflow.com/users/5887913/andrea-s): https://stackoverflow.com/a/55513524 # Warning: Relies on undocumented behaviour of the Windows Shell # and may break with any update. # Last tested on Windows 11 Home 22000.978. Add-Type -ReferencedAssemblies $(if ($PSVersionTable.PSEdition -eq "Desktop") {"System.Drawing.dll"} else {$null}) -Language CSharp -TypeDefinition @' using System; using System.Diagnostics; using System.Drawing; using System.Runtime.InteropServices; public class TouchKeyboardController { public static void ToggleTouchKeyboard() { try { UIHostNoLaunch uiHostNoLaunch = new UIHostNoLaunch(); ((ITipInvocation)uiHostNoLaunch).Toggle(GetDesktopWindow()); Marshal.ReleaseComObject(uiHostNoLaunch); } catch (COMException exc) { if (exc.HResult == unchecked((int)0x80040154)) // REGDB_E_CLASSNOTREG { ProcessStartInfo processStartInfo = new ProcessStartInfo("TabTip.exe") { UseShellExecute = true }; using (Process process = Process.Start(processStartInfo)) { } } else { throw; } } } [ComImport, Guid("4ce576fa-83dc-4F88-951c-9d0782b4e376")] class UIHostNoLaunch { } [ComImport, Guid("37c994e7-432b-4834-a2f7-dce1f13b834b")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface ITipInvocation { void Toggle(IntPtr hwnd); } [DllImport("user32.dll", SetLastError = false)] static extern IntPtr GetDesktopWindow(); public static bool IsInputPaneOpen() { FrameworkInputPane frameworkInputPane = new FrameworkInputPane(); Rectangle rect; ((IFrameworkInputPane)frameworkInputPane).Location(out rect); Marshal.ReleaseComObject(frameworkInputPane); return !rect.IsEmpty; } [ComImport, Guid("d5120aa3-46ba-44c5-822d-ca8092c1fc72")] public class FrameworkInputPane { } [ComImport, Guid("5752238b-24f0-495a-82f1-2fd593056796")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IFrameworkInputPane { int Advise([MarshalAs(UnmanagedType.IUnknown)] object pWindow, [MarshalAs(UnmanagedType.IUnknown)] object pHandler, out int pdwCookie); int AdviseWithHWND(IntPtr hwnd, [MarshalAs(UnmanagedType.IUnknown)] object pHandler, out int pdwCookie); int Unadvise(int pdwCookie); int Location(out Rectangle prcInputPaneScreenLocation); } } '@ # Toggle the Touch Keyboard regardless of whether it is currently shown or not. #[TouchKeyboardController]::ToggleTouchKeyboard() # Alternatively, if you only want to show the Touch Keyboard # and not hide it if it is already active: if ([TouchKeyboardController]::IsInputPaneOpen()) { [TouchKeyboardController]::ToggleTouchKeyboard() }