I have a program that captures all key presses using pyHook, then runs a few functions.
I notice that after a while (of random duration), the program was stop receiving key triggers, even though I am pressing keys?
Is pyHook unstable?
I'm not changing what keys are pressed or pressing them prematurely or anything like that.
Here's my code:
import time
import win32api
import win32con
import pythoncom
import pyHook
import os
import ctypes
def Click(x,y):
win32api.SetCursorPos((x,y))
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,x,y,0,0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,x,y,0,0)
def DeleteRun(event):
if event.Ascii == 96:
BreakHook()
return False
Click(1250, 741)
time.sleep(0.2)
Click(649,261)
time.sleep(0.2)
Click(651, 348)
time.sleep(0.2)
Click(800, 442)
time.sleep(0.2)
Click(865, 612)
time.sleep(0.2)
Click(25, 744)
time.sleep(3)
Click(25, 744)
time.sleep(1.5)
Click(1112,297)
Click(145,392)
return True
def BreakHook():
ctypes.windll.user32.PostQuitMessage(0)
KeyGrabber = pyHook.HookManager()
KeyGrabber.KeyDown = DeleteRun
KeyGrabber.HookKeyboard()
pythoncom.PumpMessages()
Why does is suddenly stop working?
It's very frustrating as the process remains active on my computer, even if I stop the program through the IDE.
Specs:
python 2.7.2
Windows 7 (32)
Similar (dare I say identical?) problems were discussed and resolved here: pyHook + pythoncom stop working after too much keys pressed [Python] and here: Pyhook stops capturing key events after 6 presses
You may be trying to do to much from withing the event callback.
Any event function callback as configured via HookManager and PumpMessages should return as quickly as possible.
When you press a key, Windows is kind enough to inform you of the event, but there may be other programs who also need the event. You are doing sleep calls within your event, but while you sleep, Windows is waiting for your response on THIS callback.
My guess is that after a certain number of opportunities to return in a timely manner, your event registration is being voided and ignored by Windows.
Move your sleep commands outside of the event, and instead trigger your actually click-sleep sequence outside of the hookmanager callback.
Edit: Links/Reference:
The PyHook API Documentation is one of the best (unfortunately), http://pyhook.sourceforge.net/doc_1.5.0/ If you notice the many things you can do from within the event, it becomes clear why time is of the essence. Windows wants to know how to handle the keypress (for example), and keypresses happen very fast, so it wants to know ASAP.
Its important to understand that PyHook is a very thin layer, and most of the functionality is provided by Windows, so the best documents are from MSDN http://msdn.microsoft.com/en-us/library/ms632589(v=vs.85).aspx. Also might want to take a look up a level at some of the information on 'Messages' (thats where our PumpMessages ultimately derives) The written text is very descriptive, and many of the constants and values are reflected properly through PyHook, although the good code segments are not written in Python.
Here is a pretty direct reference to proper handling of Messages (which is what hookmanager knows how to get, and by which PumpMessages delivers), http://msdn.microsoft.com/en-us/library/ms644927(v=vs.85).aspx
If a top-level window stops responding to messages for more than several seconds, the system considers the window to be not responding.
and
Message Handling An application must remove and process messages posted to the message queues of its threads
When you call your sleeps, you are hanging in your current message, and neglecting the others that might be stacking up. Even if you grab the message and immediately return, Windows doesn't care what you do with it, as long as you are consuming.
来源:https://stackoverflow.com/questions/9763053/pyhook-stops-receiving-key-press-events-randomly