Electron---监听系统级键盘和鼠标事件

7,634 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

需求&&解决思路

描述:Electron应用程序最小化后5分钟内,如果电脑未进行任何操作,我们需要让Electron做一些事情。

思路:我想要实现这个功能那不是得监听键盘和鼠标事件,于是乎就按照这个思路来。

准备工作(Demo一个Electron应用)

  • 新建一个文件夹名字为Demon1
  • 新建一个package.json文件、index.js主进程文件、index.html渲染进程文件
  • 控制台键入npm init初始化之后安装依赖npm i electron -D或者应yarn或者cnpm
  • 修改package.json文件
{
  "name": "Demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "chcp 65001 && electron ."
  },
  "author": "onion",
  "license": "ISC",
  "dependencies": {
    "electron": "^18.2.0"
  }
}
  • 运行npm run start

Electron官方文档(结果并不符合要求,失败+1)

实现步骤

  • 主进程中获取当前激活的Electron窗口
  • 调用webContents中的before-input-event事件
  • 在对应的回调中做对应的操作

代码如下

  const win1 = BrowserWindow.getFocusedWindow();//获取当前活动的窗口
    // 当在激活窗口使用键盘时触发
    win1.webContents.on("before-input-event", (event, input) => {
      console.log("使用了键盘" + input.key + "键");
    })

问题

  • 只有当Electron应用程序激活状态才可以触发事件
  • 只有在Electron窗口内才可以触发事件

-------所以这个是不符合要求的,并没有监听到全局的键盘事件。

百度寻求资源和解决方案(失败+2!!成功+1)

使用node模块node-keypress(失败+1)

const { NodeKeyboard } = require("node-keypress")
const keyboard = new NodeKeyboard()
keyboard.onKeypress(function(key) {
    console.log(key)
})

------------结果报错,说process.stdin.setRawMode(true)不是一个函数。于是就把他注释了,然后就没有任何效果了,网上也查找了看了下,说是注释了也没事,这个方案还是行不通。放弃!!

使用node中的readline模块(失败+1)

const readline = require('readline');
readline.emitKeypressEvents(process.stdin);
process.stdin.setRawMode(true);
process.stdin.on('keypress', (str, key) => {
    console.log(str)
    console.log(key)
    if(key.ctrl === true && key.name === 'd'){
        process.exit(0)
    }
})

------------结果还是报错,和上面的一样。于是乎我就打断点看到底怎么回事儿,发现它在源码里面封装了,然后我尝试寻求解决办法,加了一个判断然后再执行或者不执行那个方法,结果什么效果也没有。放弃!!

使用iohook来实现

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "chcp 65001 && electron .",
    //需要重新build一下
    "rebuildnew": "npm rebuild --runtime=electron --target=18.2.0 --disturl=https://atom.io/download/atom-shell --abi=103"//对应项目中electron版本
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "electron": "^18.2.0"
  },
  //iohook配置项
  "iohook": {
    "targets": [
      "node-93",//对应node版本
      "electron-103"//对应electron版本
    ],
    "platforms": [
      "win32",
      "darwin",
      "linux"
    ],
    "arches": [
      "x64",
      "ia32"
    ]
  }
}
  • 运行Demo终于成功了
  • 放上主进程中的代码
const ioHook = require('iohook');
ioHook.start(false);
const eventHandler =function(type){
    switch (type) {
        case 'mouseclick':
            console.log('mouse is click!')
            break;
        case 'mousedown':
            console.log('mouse is press!')
            break;
        case 'mouseup':
            console.log('mouse is release!')
            break;
        case 'mousedrag':
            console.log('mouse is moving!')
            break;
        case 'mousedrag':
            console.log('mouse is moving!')
            break;
        case 'mousewheel':
            console.log('keybord is rolling!')
            break;
        case 'keydown':
            console.log('keybord is press!')
            break;
        default:
            console.log('move mouse or keyboard try it!')
            break;
    }
}
ioHook.start(false);
ioHook.on('mouseclick', ()=>{eventHandler('mouseclick')});
ioHook.on('mousedown', ()=>{eventHandler('mousedown')});
ioHook.on('mouseup', ()=>{eventHandler('mouseup')});
ioHook.on('mousedrag', ()=>{eventHandler('mousedrag')});
ioHook.on('mousewheel', ()=>{eventHandler('mousewheel')});
ioHook.on('mouse', ()=>{eventHandler('mousedrag')});
ioHook.on('keyup', ()=>{eventHandler('keyup')});
ioHook.on('keydown', ()=>{eventHandler('keydown')});
app.on('before-quit', () => {
// 卸载iohook监听
ioHook.unload();
ioHook.stop();
});

效果如下:

下载.gif