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

实现Electron应用开机时以后台进程启动

实现Electron应用开机时以后台进程启动

我特别懂你这个需求——做了个靠通知干活的Electron应用,总不能每次开机都手动点开UI吧?之前用auto-launch没搞定也正常,很多人只配置了启动项,却没处理Electron启动时的窗口显示逻辑,我给你梳理两个靠谱的实现方案,亲测有效:

方案一:优化auto-launch配置+区分启动场景

如果你还想用之前的auto-launch,那得补全窗口控制的逻辑,不然开机启动还是会弹出UI:

  1. 先确认依赖安装没问题:
npm install auto-launch --save
  1. 在主进程代码(比如main.js)里,通过启动参数判断是否为开机启动,再决定是否显示窗口:
const { app, BrowserWindow } = require('electron');
const AutoLaunch = require('auto-launch');

let mainWindow;

function createWindow() {
  // 初始化窗口时默认隐藏
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    show: false,
    webPreferences: {
      // 根据你的Electron版本调整配置,新版推荐开启contextIsolation
      contextIsolation: true,
      preload: `${__dirname}/preload.js`
    }
  });

  // 判断是否是开机启动场景:检查启动参数里的--startup
  const isStartupLaunch = process.argv.some(arg => arg === '--startup');
  // 只有用户手动打开应用时,才显示窗口
  if (!isStartupLaunch) {
    mainWindow.show();
  }

  mainWindow.loadFile('index.html');

  mainWindow.on('closed', () => {
    mainWindow = null;
  });
}

// 配置auto-launch,关键要传递--startup参数
const appLauncher = new AutoLaunch({
  name: '你的应用名称', // 必须和package.json里的name字段一致
  path: app.getPath('exe'),
  args: ['--startup']
});

// 启用开机启动
appLauncher.enable();

// 可选:验证启动项是否注册成功
appLauncher.isEnabled().then(enabled => {
  enabled && console.log('开机启动已成功配置');
}).catch(err => console.error('配置开机启动失败:', err));

app.whenReady().then(() => {
  createWindow();

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
});

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit();
});

方案二:用Electron官方API(推荐,无第三方依赖)

Electron本身就自带了开机启动的API app.setLoginItemSettings,兼容性比第三方包更好,直接用它更省心:

const { app, BrowserWindow } = require('electron');
const path = require('path');

let mainWindow;

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    show: false,
    webPreferences: {
      contextIsolation: true,
      preload: path.join(__dirname, 'preload.js')
    }
  });

  // 判断是否为开机启动:用官方API获取启动状态
  const isStartup = app.getLoginItemSettings().wasOpenedAsHidden;
  // 手动打开时才显示窗口
  if (!isStartup) {
    mainWindow.show();
  }

  mainWindow.loadFile('index.html');

  mainWindow.on('closed', () => {
    mainWindow = null;
  });
}

app.whenReady().then(() => {
  createWindow();

  // 配置开机启动,核心是openAsHidden: true
  app.setLoginItemSettings({
    openAtLogin: true,
    openAsHidden: true, // 强制开机启动时隐藏窗口
    args: ['--startup'] // 可选,辅助判断启动场景
  });

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
});

// macOS特殊处理:用户从Dock点击应用时,要显示窗口
app.on('before-quit', (event) => {
  if (process.platform === 'darwin' && !mainWindow.isVisible()) {
    event.preventDefault();
    mainWindow.hide();
  }
});

关键注意事项

  • 打包后再测试:开发环境的应用路径和打包后不一样,直接在dev环境测开机启动大概率出问题,用electron-builder或electron-packager打包后再验证。
  • 跨平台适配
    • macOS:如果想让应用完全在后台(不在Dock显示),可以在electron-builder的package.json配置里加:
    "build": {
      "mac": {
        "infoPlist": {
          "LSUIElement": 1
        }
      }
    }
    
    • Linux:可以创建.desktop文件放到~/.config/autostart/目录,设置NoDisplay=true实现后台启动。
  • 避免重复启动:有些系统可能会重复触发开机启动,你可以在主进程里加单实例锁:
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
  app.quit();
} else {
  app.on('second-instance', (event, commandLine, workingDirectory) => {
    // 如果是第二次启动,手动打开窗口(如果用户需要)
    if (mainWindow) {
      if (mainWindow.isMinimized()) mainWindow.restore();
      mainWindow.show();
    }
  });
}

按上面的方案调整后,应该就能实现你想要的“开机自动后台启动,只跑通知不显示UI”的效果了,你可以先试试方案二,官方API的稳定性确实更靠谱。

内容来源于stack exchange

火山引擎 最新活动