Windows ortamında Python ile çalışıyorum ve bilinen bir oyundaki bazı görevleri otomatikleştirmek için bir komut dosyası yazdım. Görev, hem fare hem de klavye girişlerinin ağır kullanımını gerektirir. Ancak, söz konusu betiğin sadece bir sorunu var: tuş vuruşlarını uygulamaya gönderemiyor. Ben aşağıda göndermelidir en az 3 farklı yöntem denedim ve bazı varyasyonlar win32api
modülü kullanarak,Windows'ta oyunlara tuş vuruşlarını göndermek için Python'u kullanın.
İlk one (ayrıca boşuna, benzer sorular/cevaplar onda okuyun):
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
Bu konuda özel bir şey yok, herhangi bir metin editöründe, tarayıcıda mükemmel bir şekilde ("f" yazılır) çalışıyor ... Ancak, Counter-Strike gibi bir oyun açsam, tuş vuruşu "kaybolur" - hiçbir şey olmuyor. Öte yandan, Counter-Strike'nin konsolunu açarsam, tuşlarına basıldığında kayıtlı olur (not defterinde olduğu gibi). Başka bir oyunda test edildi, League of Legends, tam olarak aynı davranış. Gerçek oyunda, hiçbir tuş vuruşu algılanmaz. Ancak, sohbeti açsam (hala ingame) ve betiği yeniden çalıştırdığımda sohbet tarafından kaydediliyor. İkinci yöntem üstüne
: Yukarıdaki
shell = win32com.client.Dispatch("WScript.Shell")
shell.SendKeys("F")
tam olarak aynı davranışı. Oyunda her şey iyi çalışıyor, ve oyunda sadece sohbetler halinde çalışıyor.
Üçüncü yöntem (kredi, başka bir yığın akış iş parçacığında gönderen kişiye gider), daha gelişmiş (SendInput()
numaralı telefonu arayarak) ctypes
modülü ile. Teorik olarak, üç, bu bir gerçek, fiziksel tuş basın simüle en yakın olan:
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
... o da çalışmıyor. Garip bir şekilde, önceki üç ile aynı davranışı tam görüntüler: herhangi bir metin editörü/basit bir uygulama çalışır, oyunlar tarafından göz ardı edilir veya sadece oyun sohbet bölümünde kayıtlı.
Tahmin edersem, bu oyunlar klavye olaylarını, bu 3 yöntemin hiçbiriyle örtüşmediğim bir şekilde aldıklarını söylerler, böylece bunları göz ardı ederler.
Herhangi bir yardım için minnettar olurum. Mümkünse, CS, LoL ya da benzer oyunlarda çalışan kodların somut örnekleri ile bir başlangıç noktam olsun.
Tarayıcı tabanlı oyunlar için, Firefox tarayıcısında çalışmış olduğunuz, ancak krom için çalışmadığınız gibi temel tuşa basmayı buldum. – Oleksiy