6

I am trying to get a hook into windows and use Python to record keystrokes. For this, I'm using a LowLevelKeyboard Callback procedure.

def run():
 
 global KeyBdHook
 global messages
 
 KeyBdHook = HHook()
 messages = []
 
 start = time.time()
 #Record keystrokes for 2 seconds.
 while time.time() < (start + 2):
 KeyBdHook.hook = SetWindowsHookEx(13, KeyboardProc,
 GetModuleHandle(0), 0)
 if KeyBdHook.hook == 0:
 print 'ERROR: '+str(ctypes.windll.kernel32.GetLastError())
 UnhookWindowsHookEx(KeyBdHook.hook)
 
 print messages
 
def KeyboardProc(nCode, wParam, lParam):
 """http://msdn.microsoft.com/en-us/library/ms644985(v=vs.85).aspx"""
 
 if nCode < 0:
 return ctypes.windll.user32.GetNextHookEx(KeyBdHook.hook,
 nCode, wParam, lParam)
 else:
 ctypes.windll.kernel32.RtlMoveMemory(ctypes.addressof(KeyBdHook.kStruct),
 ctypes.c_void_p(lParam),
 ctypes.sizeof(lParam))
 
 messages.append(KeyBdHook.kStruct)
 return ctypes.windll.user32.GetNextHookEx(KeyBdHook.hook,
 nCode, wParam, lParam)
 
 
def SetWindowsHookEx(idHook, lpFn, hMod, dwThreadId):
 WinFunc = ctypes.WINFUNCTYPE(c_ulong, c_ulong, c_ulong, c_ulong)
 return ctypes.windll.user32.SetWindowsHookExA(idHook, WinFunc(lpFn), hMod, dwThreadId)
def GetModuleHandle(lpModuleName):
 return ctypes.windll.kernel32.GetModuleHandleA(lpModuleName)
def UnhookWindowsHookEx(hHook):
 return ctypes.windll.user32.UnhookWindowsHookEx(hHook)
 
class HHook(): 
 def __init__(self):
 self.hook = HHOOK
 self.kStruct = KBLLHOOKSTRUCT()
 
class KBLLHOOKSTRUCT(Structure):
 """http://msdn.microsoft.com/en-us/library/ms644967(v=vs.85).aspx"""
 
 _fields_ = [("vkCode", c_ulong),
 ("scanCode", c_ulong),
 ("flags", c_ulong),
 ("time", c_ulong),
 ("dwExtraInfo", POINTER(c_ulong))]

The problem with this is it never enters the KeyboardProc function. I'm thinking that I might have to cast it as a C-type function using ctypes.WINFUNCTYPE or ctypes.CFUNCTYPE, but I can't figure it out. Windows doesn't seem to be throwing an error on SetWindowsEx either.

I'm assuming it's not handling the KeyboardProc parameter being passed into SetWindowsEx. Any ideas on how to cast this so Windows can input data into it? Thanks.

asked Feb 16, 2011 at 21:19

1 Answer 1

6

To resurrect an old question, ThiefMaster's belief that a dll is required is not accurate. As a counter-example, I have put up a pure Python hotkey module that implements what the OP asks for. This is the Github repo.

Also, for more features, I recommend pyHook or pyhk..

Additionally, for more features, consider pywinauto, which includes a hotkey module, and much more.

answered Apr 19, 2015 at 16:58
Sign up to request clarification or add additional context in comments.

1 Comment

This is really great. I think it's useful to mention, it can work without a DLL by implementing a message loop.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.