Python pyhook
From wikinotes
http://pyhook.sourceforge.net/doc_1.5.0/ | Official PyHook API |
pyHook uses the pyWin32 module to intercept keypress events. You can simply read them, bind
your own custom actions, disable some actions etc. The standard way of getting keypress events
is by using pythoncom.PumpMessages()
. This creates an endless loop within Windows' eventLoop,
that does not quit until a WM_QUIT
message is sent to the thread. For this reason,
in the example I am starting a the call to pythoncom.PumpMessages
in a separate thread,
so that I can run a timer, and disable it when I am ready.
Mouse Events
import pythoncom, pyHook
import logging
def mouseEvent(event ):
import logging
print 'MessageName:' , event.MessageName
print 'Message:' , event.Message
print 'Time:' , event.Time
print 'Window:' , event.Window
print 'WindowName:' , event.WindowName
print 'Position:' , event.Position
print 'Wheel:' , event.Wheel
print 'Injected:' , event.Injected
print '---'
logging.info( 'MousePosition: '+ str(event.Position) )
return True
Keyboard Events
import pythoncom, pyHook
import logging
## Monitor Keypress Events
def keyDownEvent(event):
import win32api
import logging
mainThread = win32api.GetCurrentThreadId()
print 'MessageName:' , event.MessageName
print 'Message:' , event.Message
print 'Time:' , event.Time
print 'Ascii:' , event.Ascii, chr(event.Ascii)
print 'Key:' , event.Key
print 'keyID:' , event.KeyID
print 'ScanCode:' , event.ScanCode
print 'Extended:' , event.Extended
print 'Injected:' , event.Injected
print 'Alt' , event.Alt
print 'Transition' , event.Transition
print '---'
logging.info( 'Ascii:' +' '+ chr(event.Ascii) )
return True
Main Loop
def makeHook( index=None, threadTracker=None ):
""" Loop To Monitor all keystrokes/mouse movements """
import win32api
## Get win32 ThreadId (so we can kill it later)
threadId = win32api.GetCurrentThreadId()
threadTracker.threads[ index ] = threadId
## Start Monitoring Events
hook = pyHook.HookManager()
hook.MouseAll = mouseEvent
hook.KeyDown = keyDownEvent
hook.HookMouse()
hook.HookKeyboard()
pythoncom.PumpMessages()
ThreadTracker
class ThreadTracker(object):
""" Common Object to store win32ThreadIds """
def __init__(self):
self.threads = {} ## Dict of assignedIndex:win32_threadId
Run Threaded
if __name__ == '__main__':
import win32api
import win32con
import time
import threading
import logging
## Logging
logging.basicConfig(
filename = 'C:/Users/willp/Desktop/dev/pyhook/pyhook.log',
level = logging.DEBUG,
)
logging.info( 'Press Any Key, or Move the Mouse to write to the log' )
logging.info( 'This must be run directly from the CLI, and not ipython.' )
## Create Object to track Threads
trackerObj = ThreadTracker()
## Run win32Hook in a separate thread (so we can continue working here)
index = 0
t = threading.Thread(
target = makeHook,
args = ( index, trackerObj, ),
)
t.start()
## In order to send stop PumpMessages from monitoring all
## events, you need to send a 'WM_QUIT' message to the process' thread
## In order to do this, you need to capture it's threadId.
## Wait 2 seconds, then kill the thread
time.sleep( 5 )
win32api.PostThreadMessage(
trackerObj.threads[ index ] ,
win32con.WM_QUIT ,
0 ,
0 ,
)