You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Electron应用如何发送按键?sendInputEvent存在问题求解决方案

解决Electron中跨线程模拟系统级按键的轻量方案

你提到的sendInputEvent确实有不少局限性——必须在主窗口线程调用、对系统级快捷键(比如Alt+Tab)支持有限,而且仅窗口聚焦时生效,确实不太适合你的场景。RobotJS虽然功能全,但编译和依赖问题确实麻烦,下面给你几个更轻量的替代方案:

方案1:利用系统原生工具+Electron主进程(零额外依赖)

如果只是需要触发Alt+Tab这类系统级快捷键,完全可以绕开复杂的Node模块,直接调用系统自带的脚本工具,无需安装任何额外依赖:

Windows平台(用PowerShell调用SendKeys)

// 主进程代码
const { exec } = require('child_process');
const { ipcMain } = require('electron');

function simulateAltTabAndEnter() {
  // 发送Alt+Tab
  exec('powershell -Command "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys(\'%{TAB}\')"', (err) => {
    if (err) console.error(err);
    // 等待1秒后发送Enter确认选择
    setTimeout(() => {
      exec('powershell -Command "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys(\'{ENTER}\')"');
    }, 1000);
  });
}

// 监听渲染进程的按钮点击请求
ipcMain.on('trigger-alt-tab-sequence', () => {
  simulateAltTabAndEnter();
});

macOS平台(用AppleScript模拟按键)

// 主进程代码
const { exec } = require('child_process');
const { ipcMain } = require('electron');

function simulateCmdTabAndEnter() {
  // macOS的窗口切换是Cmd+Tab
  exec('osascript -e \'tell application "System Events" to keystroke tab using command down\'', (err) => {
    if (err) console.error(err);
    setTimeout(() => {
      exec('osascript -e \'tell application "System Events" to keystroke return\'');
    }, 1000);
  });
}

ipcMain.on('trigger-alt-tab-sequence', () => {
  simulateCmdTabAndEnter();
});

然后在渲染进程给按钮绑定点击事件,向主进程发信号即可:

// 渲染进程代码
const { ipcRenderer } = require('electron');

document.getElementById('your-trigger-button').addEventListener('click', () => {
  ipcRenderer.send('trigger-alt-tab-sequence');
});

这个方案完全依赖系统自带工具,没有额外依赖,非常轻量。

方案2:使用iohook(跨平台轻量按键模拟)

如果需要更灵活的按键组合(比如自定义延迟、复杂序列),可以试试iohook——它是一个跨平台的Node.js模块,提供预编译版本(无需手动编译),体积小,API简单。

安装(无需手动编译)

npm install iohook --save

示例代码(主进程中使用)

const { ipcMain } = require('electron');
const ioHook = require('iohook');

// 初始化iohook
ioHook.start();

function simulateAltTabSequence() {
  // 模拟Alt按下
  ioHook.emit('keydown', { keycode: 18 });
  // 模拟Tab按下+释放
  ioHook.emit('keydown', { keycode: 9 });
  ioHook.emit('keyup', { keycode: 9 });
  // 模拟Alt释放
  ioHook.emit('keyup', { keycode: 18 });

  // 1秒后发送Enter
  setTimeout(() => {
    ioHook.emit('keydown', { keycode: 13 });
    ioHook.emit('keyup', { keycode: 13 });
  }, 1000);
}

ipcMain.on('trigger-key-sequence', () => {
  simulateAltTabSequence();
});

渲染进程同样通过ipcRenderer触发即可,这个方案跨平台性好,比RobotJS轻便很多。

方案3:修复sendInputEvent的使用(仅适用于窗口内按键)

如果你的需求只是在Electron窗口内模拟按键(不是系统级切换),那sendInputEvent是可以正常工作的,可能是你之前的调用流程不完整:

// 主进程代码
const { ipcMain } = require('electron');

ipcMain.on('simulate-in-window-tab', () => {
  // 先确保窗口聚焦
  win.focus();
  // 完整模拟Alt+Tab的按下+释放流程
  win.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Alt', modifiers: [] });
  win.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Tab', modifiers: ['alt'] });
  win.webContents.sendInputEvent({ type: 'keyUp', keyCode: 'Tab', modifiers: ['alt'] });
  win.webContents.sendInputEvent({ type: 'keyUp', keyCode: 'Alt', modifiers: [] });
});

不过这个方法只能模拟窗口内的按键,无法触发系统级的窗口切换,适合窗口内的交互场景。


内容的提问来源于stack exchange,提问作者John Smith

火山引擎 最新活动