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.
1 Answer 1
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.