How can I send keyboard commands (hold,release,simultanous) with a python script?
Asked Answered
K

2

5

I want to send virtually the command like this:

when keypress=="a"                   #if entered key is "a"
    send {ALT+TAB}                   # send ALT and TAB simultaneously
    sleep(2)                         #wait for 2 sec
    send {"I love my Country",0.1}   #send all strings at 0.1 sec wait
    key_down("BACKSPACE",1)          #hold down backspace key for 1 sec
    send{ALT+F4}                     #send ALT and F4 simultaneously

For all, or a particular application, also opengl games as well.

I tried SendKeys.py but there is no simultaneously input function and no key_down method for sending holding down a key command. All advice will be greatly appreciated.

Koosis answered 8/11, 2012 at 13:26 Comment(1)
Here is a solution that works for OS XKan
D
12

I know how to do it with ctypes. For example for Alt-Tab (it is a lot of boilerplate code, I know) :

import ctypes
import time

SendInput = ctypes.windll.user32.SendInput

PUL = ctypes.POINTER(ctypes.c_ulong)
class KeyBdInput(ctypes.Structure):
    _fields_ = [("wVk", ctypes.c_ushort),
                ("wScan", ctypes.c_ushort),
                ("dwFlags", ctypes.c_ulong),
                ("time", ctypes.c_ulong),
                ("dwExtraInfo", PUL)]

class HardwareInput(ctypes.Structure):
    _fields_ = [("uMsg", ctypes.c_ulong),
                ("wParamL", ctypes.c_short),
                ("wParamH", ctypes.c_ushort)]

class MouseInput(ctypes.Structure):
    _fields_ = [("dx", ctypes.c_long),
                ("dy", ctypes.c_long),
                ("mouseData", ctypes.c_ulong),
                ("dwFlags", ctypes.c_ulong),
                ("time",ctypes.c_ulong),
                ("dwExtraInfo", PUL)]

class Input_I(ctypes.Union):
    _fields_ = [("ki", KeyBdInput),
                 ("mi", MouseInput),
                 ("hi", HardwareInput)]

class Input(ctypes.Structure):
    _fields_ = [("type", ctypes.c_ulong),
                ("ii", Input_I)]

def PressKey(hexKeyCode):

    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.ki = KeyBdInput( hexKeyCode, 0x48, 0, 0, ctypes.pointer(extra) )
    x = Input( ctypes.c_ulong(1), ii_ )
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

def ReleaseKey(hexKeyCode):

    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.ki = KeyBdInput( hexKeyCode, 0x48, 0x0002, 0, ctypes.pointer(extra) )
    x = Input( ctypes.c_ulong(1), ii_ )
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))


def PressAltTab():

    PressKey(0x012) #Alt
    PressKey(0x09) #Tab

    time.sleep(2) #optional : if you want to see the atl-tab overlay

    ReleaseKey(0x09) #~Tab
    ReleaseKey(0x012) #~Alt


if __name__ =="__main__":

     PressAltTab()

A modern version would use Unicode :

KEYEVENTF_UNICODE = 0x0004 KEYEVENTF_KEYUP = 0x0002

def PressKey(KeyUnicode):

    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.ki = KeyBdInput( 0, KeyUnicode, KEYEVENTF_UNICODE, 0, ctypes.pointer(extra) )
    x = Input( ctypes.c_ulong(1), ii_ )
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

def ReleaseKey(KeyUnicode):

    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.ki = KeyBdInput( 0, KeyUnicode, KEYEVENTF_UNICODE|KEYEVENTF_KEYUP, 0, ctypes.pointer(extra) )
    x = Input( ctypes.c_ulong(1), ii_ )
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))


def PressAltTab():

    PressKey(unichr(0x12)) #Alt
    PressKey(unichr(0x09)) #Tab

    time.sleep(2) #optional : if you want to see the atl-tab overlay

    ReleaseKey(unichr(0x09)) #~Tab
    ReleaseKey(unichr(0x12)) #~Alt


if __name__ =="__main__":

     PressAltTab()
Dinitrobenzene answered 8/11, 2012 at 13:38 Comment(4)
Hi. Thank you this was very helpful, but PressKey seems to automatically release for me when testing on Windows 8. Any idea why that might be happening?Hallerson
Why do you use 0x48 as the scan code for each of your keys? Should it not also have the same value as the hexKeyCode that you are using?Cadal
You're totally right : I wrote the "legacy" ANSI-style key presses. A modern version should use Unicode.Dinitrobenzene
When I try to use unichr, it says it isn't defined.Simons
A
1

Make some additions for the upstair's answer.

Next up is the Virtual Key Code.

class VK:
    ms_l = mouse_left = vk_lbutton = VK_LBUTTON = 1
    ms_r = mouse_right = vk_rbutton = VK_RBUTTON = 2
    cancel = VK_CANCEL = 3
    ms_m = mouse_middle = vk_mbutton = VK_MBUTTON = 4

    vk_xbutton1 = VK_XBUTTON1 = 5
    vk_xbutton2 = VK_XBUTTON2 = 6



    backspace = 8
    tab = 9
    clear = 12
    # enter = 13
    # shift = 16
    # ctrl = 17
    # alt = 18
    pause = 19
    caps_lock = 20
    esc = 27
    spacebar = 32
    page_up = 33
    page_down = 34
    end = 35
    home = 36
    left_arrow = 37
    up_arrow = 38
    right_arrow = 39
    down_arrow = 40
    select = 41
    print = 42
    execute = 43
    print_screen = 44
    insert = 45
    delete = 46
    help = 47
    num_0 = 48      # keyboard virtual key code
    num_1 = 49
    num_2 = 50
    num_3 = 51
    num_4 = 52
    num_5 = 53
    num_6 = 54
    num_7 = 55
    num_8 = 56
    num_9 = 57
    a = 65
    b = 66
    c = 67
    d = 68
    e = 69
    f = 70
    g = 71
    h = 72
    i = 73
    j = 74
    k = 75
    l = 76
    m = 77
    n = 78
    o = 79
    p = 80
    q = 81
    r = 82
    s = 83
    t = 84
    u = 85
    v = 86
    w = 87
    x = 88
    y = 89
    z = 90
    numpad_0 = 96       # keypad virtual key code
    numpad_1 = 97
    numpad_2 = 98
    numpad_3 = 99
    numpad_4 = 100
    numpad_5 = 101
    numpad_6 = 102
    numpad_7 = 103
    numpad_8 = 104
    numpad_9 = 105
    multiply_key = 106
    add_key = 107
    separator_key = 108
    subtract_key = 109
    decimal_key = 110
    divide_key = 111
    F1 = 112
    F2 = 113
    F3 = 114
    F4 = 115
    F5 = 116
    F6 = 117
    F7 = 118
    F8 = 119
    F9 = 120
    F10 = 121
    F11 = 122
    F12 = 123
    F13 = 124
    F14 = 125
    F15 = 126
    F16 = 127
    F17 = 128
    F18 = 129
    F19 = 130
    F20 = 131
    F21 = 132
    F22 = 133
    F23 = 134
    F24 = 135
    num_lock = 144
    scroll_lock = 145
    left_shift = 160
    right_shift = 161
    left_control = 162
    right_control = 163
    left_menu = 164
    right_menu = 165
    browser_back = 166
    browser_forward = 167
    browser_refresh = 168
    browser_stop = 169
    browser_search = 170
    browser_favorites = 171
    browser_start_and_home = 172
    volume_mute = 173
    volume_Down = 174
    volume_up = 175
    next_track = 176
    previous_track = 177
    stop_media = 178
    play = 179
    pause_media = 179
    start_mail = 180
    select_media = 181
    start_application_1 = 182
    start_application_2 = 183
    attn_key = 246
    crsel_key = 247
    exsel_key = 248
    play_key = 250
    zoom_key = 251
    clear_key = 254

    symbol = {'+': 0xBB,
               ',': 0xBC,
               '-': 0xBD,
               '.': 0xBE,
               '/': 0xBF,
               '`': 0xC0,
               ';': 0xBA,
               '[': 0xDB,
               '\\': 0xDC,
               ']': 0xDD,
               "'": 0xDE,
               '\`': 0xC0}

    Constant = 8000 # signal
    Time = 0.5


    # hot key
    shift = 16
    ctrl = 17
    alt = 18

    f1 = 112
    f2 = 113
    f3 = 114
    f4 = 116
    f5 = 117

    enter = 13
    space = 32
    back = 8

    # keypad
    n0, n1, n2, n3, n4, n5, n6, n7, n8, n9 = 96, 97, 98, 99, 100, 101, 102, 103, 104, 105
    left, up, right, down = 37, 38, 39, 40

    def conv_ord(self, ch):     # convert data type, return: vitual_key_code
        # ch = 'q'
        if isinstance(ch, int):
            return ch
        if isinstance(ch, str):
            if ch.islower():
                ch = ch.upper()
            return ord(ch)

    1
vk = VK()

So you can use it like this way:


from ctypes_key import PressKey, ReleaseKey
from my_time import vk
import time as tt

# press any ch
def down_up(ch, t = 0.5):
    ch = vk.conv_ord(ch)
    PressKey(ch)
    tt.sleep(t)
    ReleaseKey(ch)

def main():
    ch = 'a'        # KeyDown and KeyUp
    tt.sleep(1)
    down_up(ch)

    # select all
    tt.sleep(1)
    PressKey(vk.ctrl)
    PressKey(vk.a)
    tt.sleep(0.5)
    ReleaseKey(vk.a)
    ReleaseKey(vk.ctrl)

    return 1


if __name__ == '__main__':
    main()

Github: VirtualKey_with_Ctypes

Akvavit answered 11/6, 2020 at 12:0 Comment(1)
What is the code for the 'fn' key? I can't seem to find it here.Simons

© 2022 - 2024 — McMap. All rights reserved.