Verwenden Sie Python, um Tastatureingaben an Spiele in Windows zu senden?

Ich habe mit Python in einer Windows-Umgebung gearbeitet und ein Skript geschrieben, um einige Aufgaben in einem bekannten Spiel zu automatisieren. Bei dieser Aufgabe werden Maus- und Tastatureingaben häufig verwendet.

Das Skript weist jedoch nur ein Problem auf: Es kann keine Tastenanschläge an die Anwendung senden. Ich habe mindestens 3 verschiedene Methoden ausprobiert, die ich unten veröffentlichen werde, sowie einige Variationen (lies auch Zehntel ähnlicher Fragen / Antworten, ohne Erfolg).

Erste, mit derwin32api Modul:

f = 0x46 # VirtualKey Code of the letter "F", see http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731%28v=vs.85%29.aspx 

win32api.keybd_event(f,0,0,0) # holds the "F" key down
time.sleep(2) # waits 2 seconds
win32api.keybd_event(f,0,win32con.KEYEVENTF_KEYUP,0) # releases the key

Nichts Besonderes daran, funktioniert perfekt (ein "f" ist eingegeben) in jedem Texteditor, Browser ... Wenn ich jedoch ein Spiel öffne, wie z. B. Counter-Strike, geht der Tastenanschlag "verloren" - wie in nichts passiert. Auf der anderen Seite, wenn ich Counter-Strikes Konsole öffne, dann den Tastendruckbekommt registriert (wie im Merkzettel). Getestet in einem anderen Spiel, League of Legends, genau das gleiche Verhalten. Im eigentlichen Spiel wird kein Tastendruck erkannt. Wenn ich jedoch den Chat öffne (noch)im Spiel) und starte das Skript erneut, dann wird es vom Chat registriert.

Auf die zweite Methode:

shell = win32com.client.Dispatch("WScript.Shell")
shell.SendKeys("F")

Genau das gleiche Verhalten wie oben. Funktioniert gut in allem außer im Spiel und funktioniert nur in Chats.

Dritte Methode (Gutschrift geht an denjenigen, der sie in einem anderen Stackoverflow-Thread gepostet hat), weiter fortgeschritten (Aufruf)SendInput()) mit demctypes Modul. Theoretisch simuliert dieser von den dreien am ehesten einen tatsächlichen physischen Tastendruck:

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))


def KeyPress():
    PressKey(0x46) # press F
    time.sleep(.5)
    ReleaseKey(0x46) #release F

... es geht auch nicht. Seltsamerweise zeigt es diegenau Gleiches Verhalten wie bei den vorherigen drei: Funktioniert in jedem Texteditor / jeder einfachen Anwendung, wird von Spielen ignoriert oder ist nur im Spielechat-Bereich registriert.

Wenn ich raten würde, würde ich sagen, dass diese Spiele ihre Tastaturereignisse auf eine andere Weise erhalten, die ich mit keiner dieser drei Methoden behandelt habe, und daher diese ignorieren.

Ich würde mich über jede Hilfe freuen. Wenn möglich, mit konkreten Beispielen für Code, der entweder in CS, LoL oder ähnlichen Spielen funktioniert, damit ich einen Ausgangspunkt habe.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage