title: Generating Synthetic Input tags: python windows input [Example Python Module](combopresser.py) From [this stackoverflow](https://stackoverflow.com/questions/13564851/how-to-generate-keyboard-events) Virtual Key Codes are at: [MSDN](https://learn.microsoft.com/en-gb/windows/win32/inputdev/virtual-key-codes?redirectedfrom=MSDN) See also [this stackoverflow on unicode](https://stackoverflow.com/questions/77218519/win32-send-unicode-to-application/77221232?noredirect=1#comment136250698_77221232) to see how to send unicode. Also [this stackoverflow on sending to a specific window](https://stackoverflow.com/questions/2113950/how-to-send-keystrokes-to-a-window) We use `ctypes` to call to `user32`. ```py import ctypes from ctypes import wintypes import time user32 = ctypes.WinDLL('user32', use_last_error=True) INPUT_MOUSE = 0 INPUT_KEYBOARD = 1 INPUT_HARDWARE = 2 KEYEVENTF_EXTENDEDKEY = 0x0001 KEYEVENTF_KEYUP = 0x0002 KEYEVENTF_UNICODE = 0x0004 KEYEVENTF_SCANCODE = 0x0008 MAPVK_VK_TO_VSC = 0 # msdn.microsoft.com/en-us/library/dd375731 VK_TAB = 0x09 VK_MENU = 0x12 # C struct definitions wintypes.ULONG_PTR = wintypes.WPARAM class MOUSEINPUT(ctypes.Structure): _fields_ = (("dx", wintypes.LONG), ("dy", wintypes.LONG), ("mouseData", wintypes.DWORD), ("dwFlags", wintypes.DWORD), ("time", wintypes.DWORD), ("dwExtraInfo", wintypes.ULONG_PTR)) class KEYBDINPUT(ctypes.Structure): _fields_ = (("wVk", wintypes.WORD), ("wScan", wintypes.WORD), ("dwFlags", wintypes.DWORD), ("time", wintypes.DWORD), ("dwExtraInfo", wintypes.ULONG_PTR)) def __init__(self, *args, **kwds): super(KEYBDINPUT, self).__init__(*args, **kwds) # some programs use the scan code even if KEYEVENTF_SCANCODE # isn't set in dwFflags, so attempt to map the correct code. if not self.dwFlags & KEYEVENTF_UNICODE: self.wScan = user32.MapVirtualKeyExW(self.wVk, MAPVK_VK_TO_VSC, 0) class HARDWAREINPUT(ctypes.Structure): _fields_ = (("uMsg", wintypes.DWORD), ("wParamL", wintypes.WORD), ("wParamH", wintypes.WORD)) class INPUT(ctypes.Structure): class _INPUT(ctypes.Union): _fields_ = (("ki", KEYBDINPUT), ("mi", MOUSEINPUT), ("hi", HARDWAREINPUT)) _anonymous_ = ("_input",) _fields_ = (("type", wintypes.DWORD), ("_input", _INPUT)) LPINPUT = ctypes.POINTER(INPUT) def _check_count(result, func, args): if result == 0: raise ctypes.WinError(ctypes.get_last_error()) return args user32.SendInput.errcheck = _check_count user32.SendInput.argtypes = (wintypes.UINT, # nInputs LPINPUT, # pInputs ctypes.c_int) # cbSize # Functions def PressKey(hexKeyCode): x = INPUT(type=INPUT_KEYBOARD, ki=KEYBDINPUT(wVk=hexKeyCode)) user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x)) def ReleaseKey(hexKeyCode): x = INPUT(type=INPUT_KEYBOARD, ki=KEYBDINPUT(wVk=hexKeyCode, dwFlags=KEYEVENTF_KEYUP)) user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x)) def AltTab(): """Press Alt+Tab and hold Alt key for 2 seconds in order to see the overlay. """ PressKey(VK_MENU) # Alt PressKey(VK_TAB) # Tab ReleaseKey(VK_TAB) # Tab~ time.sleep(2) ReleaseKey(VK_MENU) # Alt~ if __name__ == "__main__": AltTab() ``` # Unicode From [this stackoverflow](https://stackoverflow.com/questions/77218519/win32-send-unicode-to-application/77221232?noredirect=1#comment136250698_77221232) ```cpp #include #include void SendInputString(const std::wstring &str) { int len = str.length(); if (len == 0) return; std::vector in(len*2); ZeroMemory(&in[0], in.size()*sizeof(INPUT)); int i = 0, idx = 0; while (i < len) { WORD ch = (WORD) str[i++]; if ((ch < 0xD800) || (ch > 0xDFFF)) { in[idx].type = INPUT_KEYBOARD; in[idx].ki.wScan = ch; in[idx].ki.dwFlags = KEYEVENTF_UNICODE; ++idx; in[idx] = in[idx-1]; in[idx].ki.dwFlags |= KEYEVENTF_KEYUP; ++idx; } else { in[idx].type = INPUT_KEYBOARD; in[idx].ki.wScan = ch; in[idx].ki.dwFlags = KEYEVENTF_UNICODE; ++idx; in[idx].type = INPUT_KEYBOARD; in[idx].ki.wScan = (WORD) str[i++]; in[idx].ki.dwFlags = KEYEVENTF_UNICODE; ++idx; in[idx] = in[idx-2]; in[idx].ki.dwFlags |= KEYEVENTF_KEYUP; ++idx; in[idx] = in[idx-2]; in[idx].ki.dwFlags |= KEYEVENTF_KEYUP; ++idx; } } SendInput(in.size(), &in[0], sizeof(INPUT)); } ``` # Sending To A Window From [this stackoverflow](https://stackoverflow.com/questions/2113950/how-to-send-keystrokes-to-a-window) ```cpp int SendKeystrokesToNotepad( const TCHAR *const text ) { INPUT *keystroke; UINT i, character_count, keystrokes_to_send, keystrokes_sent; HWND notepad; assert( text != NULL ); //Get the handle of the Notepad window. notepad = FindWindow( _T( "Notepad" ), NULL ); if( notepad == NULL ) return 0; //Bring the Notepad window to the front. if( !SetForegroundWindow( notepad ) ) return 0; //Fill in the array of keystrokes to send. character_count = _tcslen( text ); keystrokes_to_send = character_count * 2; keystroke = new INPUT[ keystrokes_to_send ]; for( i = 0; i < character_count; ++i ) { keystroke[ i * 2 ].type = INPUT_KEYBOARD; keystroke[ i * 2 ].ki.wVk = 0; keystroke[ i * 2 ].ki.wScan = text[ i ]; keystroke[ i * 2 ].ki.dwFlags = KEYEVENTF_UNICODE; keystroke[ i * 2 ].ki.time = 0; keystroke[ i * 2 ].ki.dwExtraInfo = GetMessageExtraInfo(); keystroke[ i * 2 + 1 ].type = INPUT_KEYBOARD; keystroke[ i * 2 + 1 ].ki.wVk = 0; keystroke[ i * 2 + 1 ].ki.wScan = text[ i ]; keystroke[ i * 2 + 1 ].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; keystroke[ i * 2 + 1 ].ki.time = 0; keystroke[ i * 2 + 1 ].ki.dwExtraInfo = GetMessageExtraInfo(); } //Send the keystrokes. keystrokes_sent = SendInput( ( UINT )keystrokes_to_send, keystroke, sizeof( *keystroke ) ); delete [] keystroke; return keystrokes_sent == keystrokes_to_send; } ``` # Key Codes From MSDN linked above. ```csv sep=@ VK_LBUTTON@0x01@Left mouse button VK_RBUTTON@0x02@Right mouse button VK_CANCEL@0x03@Control-break processing VK_MBUTTON@0x04@Middle mouse button VK_XBUTTON1@0x05@X1 mouse button VK_XBUTTON2@0x06@X2 mouse button -@0x07@Reserved VK_BACK@0x08@BACKSPACE key VK_TAB@0x09@TAB key -@0x0A-0B@Reserved VK_CLEAR@0x0C@CLEAR key VK_RETURN@0x0D@ENTER key -@0x0E-0F@Unassigned VK_SHIFT@0x10@SHIFT key VK_CONTROL@0x11@CTRL key VK_MENU@0x12@ALT key VK_PAUSE@0x13@PAUSE key VK_CAPITAL@0x14@CAPS LOCK key VK_KANA@0x15@IME Kana mode VK_HANGUL@0x15@IME Hangul mode VK_IME_ON@0x16@IME On VK_JUNJA@0x17@IME Junja mode VK_FINAL@0x18@IME final mode VK_HANJA@0x19@IME Hanja mode VK_KANJI@0x19@IME Kanji mode VK_IME_OFF@0x1A@IME Off VK_ESCAPE@0x1B@ESC key VK_CONVERT@0x1C@IME convert VK_NONCONVERT@0x1D@IME nonconvert VK_ACCEPT@0x1E@IME accept VK_MODECHANGE@0x1F@IME mode change request VK_SPACE@0x20@SPACEBAR VK_PRIOR@0x21@PAGE UP key VK_NEXT@0x22@PAGE DOWN key VK_END@0x23@END key VK_HOME@0x24@HOME key VK_LEFT@0x25@LEFT ARROW key VK_UP@0x26@UP ARROW key VK_RIGHT@0x27@RIGHT ARROW key VK_DOWN@0x28@DOWN ARROW key VK_SELECT@0x29@SELECT key VK_PRINT@0x2A@PRINT key VK_EXECUTE@0x2B@EXECUTE key VK_SNAPSHOT@0x2C@PRINT SCREEN key VK_INSERT@0x2D@INS key VK_DELETE@0x2E@DEL key VK_HELP@0x2F@HELP key 0x30@0 key 0x31@1 key 0x32@2 key 0x33@3 key 0x34@4 key 0x35@5 key 0x36@6 key 0x37@7 key 0x38@8 key 0x39@9 key -@0x3A-40@Undefined 0x41@A key 0x42@B key 0x43@C key 0x44@D key 0x45@E key 0x46@F key 0x47@G key 0x48@H key 0x49@I key 0x4A@J key 0x4B@K key 0x4C@L key 0x4D@M key 0x4E@N key 0x4F@O key 0x50@P key 0x51@Q key 0x52@R key 0x53@S key 0x54@T key 0x55@U key 0x56@V key 0x57@W key 0x58@X key 0x59@Y key 0x5A@Z key VK_LWIN@0x5B@Left Windows key VK_RWIN@0x5C@Right Windows key VK_APPS@0x5D@Applications key -@0x5E@Reserved VK_SLEEP@0x5F@Computer Sleep key VK_NUMPAD0@0x60@Numeric keypad 0 key VK_NUMPAD1@0x61@Numeric keypad 1 key VK_NUMPAD2@0x62@Numeric keypad 2 key VK_NUMPAD3@0x63@Numeric keypad 3 key VK_NUMPAD4@0x64@Numeric keypad 4 key VK_NUMPAD5@0x65@Numeric keypad 5 key VK_NUMPAD6@0x66@Numeric keypad 6 key VK_NUMPAD7@0x67@Numeric keypad 7 key VK_NUMPAD8@0x68@Numeric keypad 8 key VK_NUMPAD9@0x69@Numeric keypad 9 key VK_MULTIPLY@0x6A@Multiply key VK_ADD@0x6B@Add key VK_SEPARATOR@0x6C@Separator key VK_SUBTRACT@0x6D@Subtract key VK_DECIMAL@0x6E@Decimal key VK_DIVIDE@0x6F@Divide key VK_F1@0x70@F1 key VK_F2@0x71@F2 key VK_F3@0x72@F3 key VK_F4@0x73@F4 key VK_F5@0x74@F5 key VK_F6@0x75@F6 key VK_F7@0x76@F7 key VK_F8@0x77@F8 key VK_F9@0x78@F9 key VK_F10@0x79@F10 key VK_F11@0x7A@F11 key VK_F12@0x7B@F12 key VK_F13@0x7C@F13 key VK_F14@0x7D@F14 key VK_F15@0x7E@F15 key VK_F16@0x7F@F16 key VK_F17@0x80@F17 key VK_F18@0x81@F18 key VK_F19@0x82@F19 key VK_F20@0x83@F20 key VK_F21@0x84@F21 key VK_F22@0x85@F22 key VK_F23@0x86@F23 key VK_F24@0x87@F24 key -@0x88-8F@Reserved VK_NUMLOCK@0x90@NUM LOCK key VK_SCROLL@0x91@SCROLL LOCK key -@0x92-96@OEM specific -@0x97-9F@Unassigned VK_LSHIFT@0xA0@Left SHIFT key VK_RSHIFT@0xA1@Right SHIFT key VK_LCONTROL@0xA2@Left CONTROL key VK_RCONTROL@0xA3@Right CONTROL key VK_LMENU@0xA4@Left ALT key VK_RMENU@0xA5@Right ALT key VK_BROWSER_BACK@0xA6@Browser Back key VK_BROWSER_FORWARD@0xA7@Browser Forward key VK_BROWSER_REFRESH@0xA8@Browser Refresh key VK_BROWSER_STOP@0xA9@Browser Stop key VK_BROWSER_SEARCH@0xAA@Browser Search key VK_BROWSER_FAVORITES@0xAB@Browser Favorites key VK_BROWSER_HOME@0xAC@Browser Start and Home key VK_VOLUME_MUTE@0xAD@Volume Mute key VK_VOLUME_DOWN@0xAE@Volume Down key VK_VOLUME_UP@0xAF@Volume Up key VK_MEDIA_NEXT_TRACK@0xB0@Next Track key VK_MEDIA_PREV_TRACK@0xB1@Previous Track key VK_MEDIA_STOP@0xB2@Stop Media key VK_MEDIA_PLAY_PAUSE@0xB3@Play/Pause Media key VK_LAUNCH_MAIL@0xB4@Start Mail key VK_LAUNCH_MEDIA_SELECT@0xB5@Select Media key VK_LAUNCH_APP1@0xB6@Start Application 1 key VK_LAUNCH_APP2@0xB7@Start Application 2 key -@0xB8-B9@Reserved VK_OEM_1@0xBA@Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the ;: key VK_OEM_PLUS@0xBB@For any country/region, the + key VK_OEM_COMMA@0xBC@For any country/region, the , key VK_OEM_MINUS@0xBD@For any country/region, the - key VK_OEM_PERIOD@0xBE@For any country/region, the . key VK_OEM_2@0xBF@Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the /? key VK_OEM_3@0xC0@Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the `~ key -@0xC1-DA@Reserved VK_OEM_4@0xDB@Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the [{ key VK_OEM_5@0xDC@Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the \\| key VK_OEM_6@0xDD@Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the ]} key VK_OEM_7@0xDE@Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the '" key VK_OEM_8@0xDF@Used for miscellaneous characters; it can vary by keyboard. -@0xE0@Reserved -@0xE1@OEM specific VK_OEM_102@0xE2@The <> keys on the US standard keyboard, or the \\| key on the non-US 102-key keyboard -@0xE3-E4@OEM specific VK_PROCESSKEY@0xE5@IME PROCESS key -@0xE6@OEM specific VK_PACKET@0xE7@Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP -@0xE8@Unassigned -@0xE9-F5@OEM specific VK_ATTN@0xF6@Attn key VK_CRSEL@0xF7@CrSel key VK_EXSEL@0xF8@ExSel key VK_EREOF@0xF9@Erase EOF key VK_PLAY@0xFA@Play key VK_ZOOM@0xFB@Zoom key VK_NONAME@0xFC@Reserved VK_PA1@0xFD@PA1 key VK_OEM_CLEAR@0xFE@Clear key ```