Search code examples
powershellaccessibilityhotkeys

Disable SHIFT Stickykey shortcut


I'm trying to disable the popout that appears when pressing shift 5 times. Despite setting the HKCU\Control Panel\Accessibility\StickyKeys\Flags key to the 506 value in the registry, the change is not automatically applied.

I tried the code below in powershell, but to no avail:

$SKHA = Add-Type -MemberDefinition '[DllImport("user32.dll", EntryPoint = "SystemParametersInfo")] public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, uint vParam, uint init);' -Name 'Test' -PassThru;
$SKHA::SystemParametersInfo(0x003B, 0, 4, 0)

The documents I used were:

SystemParametersInfoA function (winuser.h)

STICKYKEYS structure (winuser.h)

Is there any way to disable this popout without the user having to manually disable or log off/restart the system after changing the registry?

Thank you in advance.


Solution

  • As explained by mklement0 you need to use the STICKYKEYS structure. Here is a working snippet based on following answer which first, read the current data then apply the parameter

    $MethodDefinition = @'
    [StructLayout(LayoutKind.Sequential)]
    public struct STICKYKEYS
    {
        public uint cbSize;
        public int dwFlags;
    }
    
    [DllImport("user32.dll")]
    public static extern int SystemParametersInfo(int uiAction, int uiParam, out STICKYKEYS pvParam, int fWinIni);
    '@
    $get = 0x003A
    $set = 0x003B
    $WinApiVariable = Add-Type -MemberDefinition $MethodDefinition -Name 'Win32' -NameSpace '' -PassThru
    $startupStickyKeys = New-Object -TypeName 'Win32+STICKYKEYS'
    $startupStickyKeys.cbSize = [System.Runtime.InteropServices.Marshal]::SizeOf($startupStickyKeys)
    [Win32]::SystemParametersInfo($get, [System.Runtime.InteropServices.Marshal]::SizeOf($startupStickyKeys), [ref]$startupStickyKeys, 0)
    Write-Host "Current:"
    $startupStickyKeys.dwFlags
    Write-host "Set current flag to disabled (506)"
    $startupStickyKeys.dwFlags = 506
    [Win32]::SystemParametersInfo($set, [System.Runtime.InteropServices.Marshal]::SizeOf($startupStickyKeys), [ref]$startupStickyKeys, 0)