Electron防止渲染进程(窗口)休眠、防止系统休眠

前言

当使用Electron开发的客户端,如果长时间处于后台,会进入休眠状态,暂停JS的执行。

禁止窗口休眠

Electron 窗口默认在后台时会进入「休眠状态」(暂停渲染进程的 JS 执行)。

通过配置 backgroundThrottling: false 可禁用该行为,让后台窗口继续运行任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// main.js 主进程
const { BrowserWindow } = require('electron');

let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true, // 按需启用(Electron 12+ 需配合 contextIsolation: false)
contextIsolation: false,
},
// 关键配置:禁用后台休眠
backgroundThrottling: false,
});

mainWindow.loadURL('your-page-url'); // 加载你的页面
}

app.whenReady().then(createWindow);

防止应用休眠

定时发送消息

这个是为了防止应用休眠。

1
2
3
4
5
6
7
8
if (mainWindow) {
mainWindow.webContents.on("did-finish-load", () => {
setInterval(() => {
// 发送一个空消息
mainWindow.webContents.send("keep-alive", {});
}, 10000); // 每10秒发送一次
});
}

窗口置顶(无效)

那么设置窗口指定能阻止休眠吗?

窗口「置顶显示」(始终悬浮在其他窗口上方),并不会直接禁用窗口的后台休眠

1
mainWindow.setAlwaysOnTop(true);

防止系统休眠

Electron自带的API。

阻止系统进入低功耗 (休眠) 模式。

1
powerSaveBlocker.start(type)

参数说明:

type(string) - 阻止方式:

  • prevent-app-suspension - 阻止应用被暂停。 保持系统活动状态,但允许屏幕关闭。

    实例:下载文件或播放音频。

  • prevent-display-sleep - 防止显示器进入休眠状态。 保持系统和屏幕的活跃性。

    实例:播放视频。

主进程触发

运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const powerSaveBlocker = require('electron').powerSaveBlocker;

let blockerId = null; // 用于记录阻止器 ID,后续需释放

// 程序启动后,立即阻止休眠
app.whenReady().then(() => {
// 创建阻止器:类型可选 2 种
// - 'prevent-app-suspension':仅阻止应用挂起(允许屏幕关闭,如播放音频时)
// - 'prevent-display-sleep':阻止屏幕关闭 + 系统休眠(如视频播放、实时操作时)
blockerId = powerSaveBlocker.start('prevent-display-sleep');

// 验证是否生效(返回 true 表示成功)
console.log('是否阻止休眠成功?', powerSaveBlocker.isStarted(blockerId));
});

// 程序退出时,释放阻止器(关键!避免占用系统资源)
app.on('will-quit', () => {
if (blockerId && powerSaveBlocker.isStarted(blockerId)) {
powerSaveBlocker.stop(blockerId);
console.log('已释放休眠阻止');
}
});

渲染进程触发

如果需要在渲染进程(如 Vue/React 页面)通过按钮 “开启 / 关闭防休眠”,需通过 IPC 与主进程通信:

主进程(main.js)

运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const { ipcMain } = require('electron');
const powerSaveBlocker = require('electron').powerSaveBlocker;

// 接收渲染进程的开启请求
ipcMain.handle('start-prevent-sleep', () => {
if (!blockerId || !powerSaveBlocker.isStarted(blockerId)) {
blockerId = powerSaveBlocker.start('prevent-display-sleep');
}
return powerSaveBlocker.isStarted(blockerId);
});

// 接收渲染进程的关闭请求
ipcMain.handle('stop-prevent-sleep', () => {
if (blockerId && powerSaveBlocker.isStarted(blockerId)) {
powerSaveBlocker.stop(blockerId);
blockerId = null;
return true;
}
return false;
});

渲染进程

运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const { ipcRenderer } = require('electron');

// 开启防休眠
async function startPreventSleep() {
const success = await ipcRenderer.invoke('start-prevent-sleep');
alert(success ? '已开启防休眠' : '开启失败');
}

// 关闭防休眠
async function stopPreventSleep() {
const success = await ipcRenderer.invoke('stop-prevent-sleep');
alert(success ? '已关闭防休眠' : '关闭失败');
}

// 页面按钮绑定
// <button @click="startPreventSleep()">开启防休眠</button>
// <button @click="stopPreventSleep()">关闭防休眠</button>