Search code examples
pythonkeyboardpywin32

Python pywin32 - VK_SLEEP press not working


I found this solution for pressing virtual keys: https://stackoverflow.com/a/10441322/3448364 But, problem is that VK_SLEEP not working for me. I tried with all other VK_ keys (like VK_VOLUME_UP, VK_MEDIA_NEXT_TRACK...) and it works, only VK_SLEEP not working. This is my code:

VK_SLEEP = 0x5F
hwcode = win32api.MapVirtualKey(VK_SLEEP, 0)
win32api.keybd_event(VK_SLEEP, hwcode)

When I execute that code, nothig happens. When I change virtual key to ie. VK_VOLUME_UP: works like a charm! So, code is OK, but for some reason script won't put PC in sleep with VK_SLEEP. This is source for VK_ codes that I use: https://learn.microsoft.com/en-us/windows/desktop/inputdev/virtual-key-codes

Just to be clear: my keyboard doesn't have dedicated Sleep button. But, doesn't have "volume up" too, and 0xAF (vlume_up) works. So, I don't think problem is keyboard (it's CM MK750).


Solution

  • Simulating VK_SLEEP will not have any effect, probably for security reasons.

    Changing the systems's power state requires SE_SHUTDOWN_NAME privileges. If privileges is changed successfully, you can use SetSuspendState to put the computer to sleep.

    import win32api
    import win32security
    import ctypes
    
    def sleep_mode():
        access = (win32security.TOKEN_ADJUST_PRIVILEGES | win32security.TOKEN_QUERY)
        htoken = win32security.OpenProcessToken(win32api.GetCurrentProcess(), access)
        if htoken:
            priv_id = win32security.LookupPrivilegeValue(None, win32security.SE_SHUTDOWN_NAME)
            win32security.AdjustTokenPrivileges(htoken, 0,
                [(priv_id, win32security.SE_PRIVILEGE_ENABLED)])
            ctypes.windll.powrprof.SetSuspendState(False, True, True)
            win32api.CloseHandle(htoken)
    
    sleep_mode()
    

    Side note,

    keybd_event pushes the key down. Make sure the key is pushed back up. Example:

    import win32api
    import win32con
    
    win32api.keybd_event(win32con.VK_VOLUME_UP, 0)
    win32api.keybd_event(win32con.VK_VOLUME_UP, 0, win32con.KEYEVENTF_KEYUP)