python 在windows下监听键盘按键

简介: python 在windows下监听键盘按键使用到的库ctypes(通过ctypes来调用Win32API, 主要就是调用钩子函数)使用的Win32APISetWindowsHookEx(), 将用户定义的钩子函数添加到钩子链中, 也就是我们的注册钩子函数UnhookWindowsH...

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()
目录
相关文章
|
19天前
|
C++ Python Windows
在Visual Studio中使用Python(Windows)
在Visual Studio中使用Python(Windows)
|
2月前
|
机器学习/深度学习 Python
在Python中监听变量值的变化
在Python中监听变量值的变化
77 2
|
3天前
|
Python Windows
Python 在 Windows 环境下的文件路径问题
在 Python 程序中,我们经常需要对文件进行操作。在 Windows 下,文件目录路径使用反斜杠“\”来分隔。然而,在 Python 代码中,反斜杠“\”是转义符,例如“\n”表示换行符、“\t”表示制表符。这样,如果继续使用“\”表示文件路径,就会产生歧义。
|
18天前
|
监控 数据可视化 数据库
【python项目推荐】键盘监控--统计打字频率
【python项目推荐】键盘监控--统计打字频率
45 13
|
14天前
|
Python Windows
在 Windows 平台下打包 Python 多进程代码为 exe 文件的问题及解决方案
在使用 Python 进行多进程编程时,在 Windows 平台下可能会出现将代码打包为 exe 文件后无法正常运行的问题。这个问题主要是由于在 Windows 下创建新的进程需要复制父进程的内存空间,而 Python 多进程机制需要先完成父进程的初始化阶段后才能启动子进程,所以在这个过程中可能会出现错误。此外,由于没有显式导入 Python 解释器,也会导致 Python 解释器无法正常工作。为了解决这个问题,我们可以使用函数。
19 5
|
18天前
|
Windows Python
每日自动发邮件(Python +QQ邮箱 + Windows 10定时任务)
每日自动发邮件(Python +QQ邮箱 + Windows 10定时任务)
每日自动发邮件(Python +QQ邮箱 + Windows 10定时任务)
|
18天前
|
Linux API 数据安全/隐私保护
在 Python 中从键盘读取用户输入
在 Python 中从键盘读取用户输入
|
18天前
|
编解码
Python-【键盘-鼠标】移动、操作、输入
Python-【键盘-鼠标】移动、操作、输入
16 0
|
2月前
|
Shell 定位技术 开发工具
[oeasy]python0015_键盘改造_将esc和capslock对调_hjkl_移动_双手正位
[oeasy] python0015_键盘改造_将 esc 和 capslock 对调_hjkl_移动_双手正位
27 3
|
2月前
|
测试技术 数据安全/隐私保护 Python
【如何学习Python自动化测试】—— 鼠标键盘操作
【如何学习Python自动化测试】—— 鼠标键盘操作
16 0