2014-04-12 2 views
10

Ich habe mit Python in einer Windows-Umgebung gearbeitet und ein Skript geschrieben, um einige Aufgaben in einem bekannten Spiel zu automatisieren. Die Aufgabe beinhaltet die Verwendung von Maus- und Tastatureingaben.Verwenden Sie Python, um Tastenanschläge an Spiele in Windows zu senden?

Das Skript hat jedoch nur ein Problem: Es kann Tastenanschläge nicht an die Anwendung senden. Ich habe mindestens 3 verschiedene Methoden ausprobiert, die ich unten posten und einige Variationen (lesen Sie auch Zehntel ähnliche Fragen/Antworten, ohne Erfolg)

erste, mit dem win32api 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 getippt) in jedem Texteditor, Browser ... Wenn ich jedoch ein Spiel wie sagen wir Counter-Strike öffne, dann wird der Tastenanschlag "verloren" - wie in nichts passiert. Auf der anderen Seite, wenn ich Counter-Strike-Konsole öffne, dann wird der Tastenanschlag registriert (wie im Editor). Getestet in einem anderen Spiel, League of Legends, genau das gleiche Verhalten. Im aktuellen Spiel wird kein Tastendruck erkannt. Wenn ich jedoch den Chat öffne (immer noch ingame) und das Skript neu starte, 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 in allen Bereichen außer dem Spiel und funktioniert nur in Chats.

Dritte Methode (Kredit geht an wer auch immer es in einem anderen Stackoverflow Thread gepostet hat), fortgeschrittener (Aufruf SendInput()) mit dem ctypes Modul. In der Theorie des drei, das eine in der Nähe ist einen tatsächlichen, physischen Tastendruck zu simulieren:

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 funktioniert auch nicht. Seltsamerweise zeigt es das genaue gleiche Verhalten wie die vorherigen drei: funktioniert in jedem Texteditor/einfache Anwendung, wird von Spielen ignoriert oder ist nur im Spiel Chat-Abschnitt registriert.

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

Ich würde jede Hilfe zu schätzen wissen. Wenn möglich, mit konkreten Beispielen für Code, der entweder in CS, LoL oder ähnlichen Spielen funktioniert, so dass ich einen Ausgangspunkt habe.

+0

Für browserbasierte Spiele, fand ich grundlegende Tasten drücken Sie wie oben beschrieben arbeitete Firefox-Browser, aber nicht für Chrome. – Oleksiy

Antwort

1

Sie könnten versuchen, die Fenster der Anwendung unter Verwendung EnumWindows() aufzuzählen und SendMessage() zu den Hauptfenstern des Spiels direkt aufzurufen.

+0

Funktioniert nicht. PostMessage() schlägt ebenfalls fehl. –

Verwandte Themen