tutorial pynput press example python python-2.7 keypress simulate

pynput - Simular pulsaciones de teclas de Python para controlar un juego



pynput enter key (2)

Estoy tratando de controlar un juego (mis dos juegos de prueba son Half Life 2 y Minecraft) usando mi Kinect y Python. Todo funciona excepto por una cosa. El juego responderá a los eventos simulados del mouse y al movimiento simulado del mouse (los eventos del mouse se realizan a través de ctypes y el movimiento del mouse se realiza mediante pywin32). Sin embargo, el problema es que los juegos ignoran las pulsaciones de teclas simuladas. Ambos tomarán las pulsaciones de tecla simuladas en la ventana de chat (Minecraft) o en la consola del desarrollador (Half Life 2), pero no mientras se juega el juego real.

He intentado varias formas de enviar las pulsaciones de teclas:

import win32com.client as client wsh = client.Dispatch(''WScript.Shell'') wsh.AppActivate(gameName) wsh.SendKeys(key)

y:

import win32api win32api.keybd_event(keyHexCode, 0, 0)

y:

import ctypes import time SendInput = ctypes.windll.user32.SendInput # C struct redefinitions 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)] # Actuals Functions 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))

Debo señalar que el código en la última no es mío, está fuera de otra pregunta aquí en Stack Overflow.

¿Alguien sabe por qué ninguno de estos trabajos y cuál es la forma correcta de hacerlo?


Acabo de tener el mismo problema al intentar simular las pulsaciones de tecla en Half-Life 2. Como dijo Robin, la solución es usar ScanCodes en lugar de VK.

Edité su último ejemplo de código de modo que use ScanCodes. Lo probé con Half-Life 2 y funciona bien:

import ctypes import time SendInput = ctypes.windll.user32.SendInput # C struct redefinitions 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)] # Actuals Functions def PressKey(hexKeyCode): extra = ctypes.c_ulong(0) ii_ = Input_I() ii_.ki = KeyBdInput( 0, hexKeyCode, 0x0008, 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( 0, hexKeyCode, 0x0008 | 0x0002, 0, ctypes.pointer(extra) ) x = Input( ctypes.c_ulong(1), ii_ ) ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x)) # directx scan codes http://www.gamespp.com/directx/directInputKeyboardScanCodes.html while (True): PressKey(0x11) time.sleep(1) ReleaseKey(0x11) time.sleep(1)


Es probable que el juego esté utilizando dispositivos DirectInput.

Por lo tanto, el juego está esperando presionar la tecla DirectInput. De acuerdo con la última publicación de este hilo del foro , DirectInput responde a los códigos de exploración, no a los VK. Puede intentar enviar pulsaciones de tecla DirectInput utilizando esta herramienta . El desarrollador también proporciona la fuente y una explicación detallada.

Si esto funciona, puedes intentar enviar códigos de escaneo apropiados en lugar de VK (lista de scancodes) .

También hay un proyecto anterior llamado DirectPython que te permite interactuar con DirectX / DirectInput.