我正在尝试连接到 Windows 并使用 Python 来记录击键。为此,我使用了 LowLevelKeyboard 回调过程。
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))]
问题是它永远不会进入 KeyboardProc 函数。我在想我可能必须使用 ctypes.WINFUNCTYPE 或 ctypes.CFUNCTYPE 将其转换为 C 类型函数,但我想不出来。 Windows 似乎也没有在 SetWindowsEx 上抛出错误。
我假设它不处理传递给 SetWindowsEx 的 KeyboardProc 参数。关于如何转换它以便 Windows 可以将数据输入其中的任何想法?谢谢。
最佳答案
复活一个老问题,ThiefMaster 认为需要 dll 的观点是不准确的。作为反例,我提出了一个纯 Python 热键模块来实现 OP 的要求。 This is the Github repo .
此外,要获得更多功能,请考虑 pywinauto ,其中包括热键模块等等。
关于python - Windows 与 Python Hook ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5022237/