我一直在Python環境中使用Python,並且編寫了一個腳本來自動完成已知遊戲中的一些任務。 該任務涉及大量使用鼠標和鍵盤輸入。使用Python將擊鍵發送到Windows中的遊戲?
然而,說腳本只有一個問題:它不能發送擊鍵到應用程序。我已經試過了,我將在下面發佈至少3種不同的方法和一些變化(也看過類似的問題/回答的十分之一,但無濟於事)
首先一個,使用win32api
模塊:
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
沒有什麼特別的,在任何文本編輯器,瀏覽器中完美地工作(打出「f」)然而,如果我打開一個像Counter-Strike這樣的遊戲,那麼擊鍵就會「丟失」沒有發生。另一方面,如果我打開Counter-Strike的控制檯,則按鍵獲得註冊(如在記事本中)。 在另一款遊戲中測試過,英雄聯盟的行爲完全一樣。在實際的遊戲中,沒有檢測到擊鍵。但是,如果我打開聊天(仍然遊戲內幕)並重新運行該腳本,則會通過聊天進行註冊。
在第二方法:
shell = win32com.client.Dispatch("WScript.Shell")
shell.SendKeys("F")
完全一樣上述行爲。在除了遊戲之外的所有遊戲中都能正常工作,並且只能在聊天中使用。
第三種方法(相當於將其發佈到另一個堆棧溢出線程的人),更高級的(調用SendInput()
)與模塊。理論上,這三者中最接近模擬實際的物理按鍵:
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
......它也不起作用。奇怪的是,它顯示精確行爲與前三個相同:在任何文本編輯器/簡單應用程序中工作,被遊戲忽略或僅在遊戲聊天部分註冊。
如果我猜測我會說這些遊戲以其他方式獲取他們的鍵盤事件,但我沒有用這三種方法中的任何一種來覆蓋,因此忽略了這些。
我很感激任何幫助。如果可能的話,在CS,LoL或類似遊戲中使用代碼的具體示例,以便我有一個出發點。
對於基於瀏覽器的遊戲,我發現上面介紹的基本按鍵是在Firefox瀏覽器上工作的,但沒有用於Chrome瀏覽器。 – Oleksiy