Как сделать, чтобы electron-приложение работало в фоновом режиме?

Нужно, чтобы eletron-приложение после закрытия работало в фоновом режиме и открывалось по горячим клавишам. Как я могу это сделать? Я добавляю приложение в трей, но после закрытия программы из трея она тоже удаляется

Вот так выглядит main.js

const { app, BrowserWindow, Menu, Tray } = require('electron')

function createWindow () {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true
    }
  })

  win.loadFile('index.html')
}

app.whenReady().then(createWindow)


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

//Tray

let tray = null
app.whenReady().then(() => {
  tray = new Tray('C:/Users/ПК/Downloads/Circle_34541.ico')
  const contextMenu = Menu.buildFromTemplate([
    { label: 'Item1', type: 'radio' },
    { label: 'Item2', type: 'radio' },
    { label: 'Item3', type: 'radio', checked: true },
    { label: 'Item4', type: 'radio' }
  ])
  tray.setToolTip('Shortcutter')
  tray.setContextMenu(contextMenu)
})

Ответы (1 шт):

Автор решения: nörbörnën

Твой код закрывая MainWindow, закрывает всё приложение.

Твоё приложение имеет Tray, так что нужно просто правильно скрыть MainWindow и при этом твоё приложение останется запущенным.

Для того чтобы при нажатии на кнопку закрытия окна x выполнялось не то действие, которое предусмотрено по умолчанию, тебе нужно объявить свой обработчик события close и переопределить поведение.

  mainWindow.on('close', (ev) => {
    if (mainWindow?.isVisible()) {
      ev.preventDefault();
      mainWindow.hide();
    }
  });

А для того чтобы при клике на иконку в трее заново открыть приложение нужно объявить обработчик click на Tray

  tray.on('click', () => {
    BrowserWindow.getAllWindows().shift().show();
  });

Полный листинг, где всё работает

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

function createWindow() {
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true
    }
  });

  mainWindow.loadFile('index.html');

  mainWindow.on('close', (ev) => {
    if (mainWindow?.isVisible()) {
      ev.preventDefault();
      mainWindow.hide();
    }
  });
}

function createTray() {
  const contextMenu = Menu.buildFromTemplate([
    { label: 'Item1', type: 'radio' },
    { label: 'Item2', type: 'radio' },
    { label: 'Item3', type: 'radio', checked: true },
    { label: 'Item4', type: 'radio' },
    { type: 'separator' },
    {
      label: 'Quit',
      accelerator: 'CmdOrCtrl+Q',
      click: () => {
        BrowserWindow.getAllWindows().forEach((w) => w.destroy());
        app.quit();
      }
    }
  ]);

  const tray = new Tray('./electron-icon.png');
  tray.setToolTip('Shortcutter');
  tray.setContextMenu(contextMenu);
  tray.on('click', () => {
    BrowserWindow.getAllWindows().shift().show();
  });
}

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

app.on('activate', () => {
  const window = BrowserWindow.getAllWindows().shift();
  if (window) {
    window.show();
  } else {
    createWindow();
  }
});

Проверено для v15.5.0, v11.2.0

→ Ссылка