通过pyHook来快速发送信息

Posted by kevin on July 25, 2020

preface

最近看了一个视频,通过 python 的 pyHook 模块来监听电脑的键盘响应事件,只要按下 ctrl 键就能得到一句随机的祖安话,然后 ctrl+v 快速粘贴发送出去就能够在游戏中跟人对喷,挺有意思的,指的是这个思路,并不是教唆大家去骂人。然后我也尝试了一下,将过程记录下来。

installation

pyHook 其实就是一个监听 Windows 键盘和鼠标事件的模块,只能用在 Windows 平台上面,因此还需要用到 pywin32 这个模块

从以下这个网站获取对应自己电脑版本的 pyHook,是个 whl 后缀的文件,只能先下载,不能直接 pip 安装,下载完之后才可以通过 pip install xx.whl 来安装

http://www.lfd.uci.edu/~gohlke/pythonlibs/#pyhook

然后就是 pywin32,同样的,也去下面这个网站下载相应版本的 pywin32,是个 exe 可执行文件,直接运行安装就可以了,它会自动检测当前环境中注册的 python 版本

https://sourceforge.net/projects/pywin32/files/pywin32/

运行完之后,导入 pythoncom 的时候可能会出现 DLL 无法动态加载的问题,需要去到 python 的 Scripts 目录找到一个脚本 pywin32_postinstall.py ,运行它,就会将两个 dll 拷贝到系统盘的 system32 目录中,应该就没啥事了。

usage

思路很简单,提前预设好一个 txt 格式的文本库,也就是我们需要快速发送的信息,我做实验就随便搞了几条

words

然后用 pyHook 监听键盘事件,当按下 ctrl 键时就随机从文本库中获取一条消息放到系统的剪贴板,然后就可以直接粘贴了,整体的代码也十分简洁,就用到了 pyHook 和 pywin32(以下头文件很多都是 pywin32 自带的,不需要安装)

import pyHook
import win32clipboard as wc
import win32con
import sys
import random
import pythoncom

array = []

def onKeyboardEvent(event):
    
    if (event.Key == 'Lcontrol'):
    
        b = random.sample(array, 1)
        setText(b[0])
    print(event.Key)
    return True

def getText():
    wc.OpenClipboard()
    t = wc.GetClipboardData(win32con.CF_UNICODETEXT)
    wc.CloseClipboard()
    return t

def setText(data):
    wc.OpenClipboard()
    wc.EmptyClipboard()
    wc.SetClipboardData(win32con.CF_UNICODETEXT, data)
    wc.CloseClipboard()

if __name__ == '__main__':
    with open('samples.txt', 'r', encoding='utf-8') as f:
        array = f.readlines()
        hm = pyHook.HookManager()
        hm.KeyDown = onKeyboardEvent
        hm.HookKeyboard()
        pythoncom.PumpMessages()

最后的效果就是下面这样,大家可以在此基础上进行更有意思的改进(注意 pyHook 是监听系统层面的事件,所以在所有界面按下键盘都会触发响应)

demo.gif

bugs

本来的目的是演示以下在微信上快速发送信息的,但是切到微信那儿按键盘就报错,后来发现不止微信,其他程序也是。上网查询,pyHook 在 python3 下会出现下面的报错,可能是因为当前窗口的选项卡上有中文,总之,目前无法解决,据说 python2 不会出现这个问题,我没有尝试过

TypeError: KeyboardSwitch() missing 8 required positional arguments: 'msg', 'vk_code', 'scan_code', 'ascii', 'flags', 'time', 'hwnd', and 'win_name'

reference

https://www.bilibili.com/video/BV1gE411o7K8

https://blog.csdn.net/DJY1992/article/details/78295675

https://zhidao.baidu.com/question/245752568362134164.html

https://blog.csdn.net/u014563989/article/details/77247659