python - Windows 与 Python Hook

标签 python c winapi hook ctypes

我正在尝试连接到 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 .

此外,对于更多功能,我推荐 pyHookpyhk. .

此外,要获得更多功能,请考虑 pywinauto ,其中包括热键模块等等。

关于python - Windows 与 Python Hook ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5022237/

相关文章:

c - 当 va_arg 接收到指针参数时,const mismatch 是否调用 UB?

c++ - 在 C++ 中将 PUNICODE_STRING 与 regex_match 结合使用

winapi - 如何获取航空和基本设计的标题栏高度和宽度

winapi - 在 win32 应用程序中嵌入 cmd 并且文本不可选择

python - twisted - 检测丢失的连接需要 30 分钟以上

python - 并行化执行按位操作的代码

c - 将十六进制字节转换为字符字符串

c - 如何在 Eclipse/w 多个二进制文件中组织一个 C 项目?

python - 为什么子类化元组和子类化列表之间存在这种差异?

python - 使用python逐行读取.trc文件并返回信息