How to send a message from main to render when the electron app closes

Viewed 1886

I have been trying to send a message from the main to the render when the app closes using webcontents but it doesn't seem to have an event where it checks if the app closed.

On the main

mainWindow.webContents.on('did-stop-loading', () => {
        mainWindow.webContents.send('ping', 'save!')
});

On the renderer

require('electron').ipcRenderer.on('ping', (event, message) => {
    console.log(message) // Prints 'save!'

    // Save json to a file.
    fs.writeFile("library.json", 'json', function(err) {
        if(err) {
            return console.log(err);
        }
        console.log("Library Saved!");
    });
});

This works but I want a way where this is run when the app closes. But webcontents doesn't seem to have a 'close' event like the window does:

mainWindow.on('close', () => {
        console.log("Run right before the app is closed");
});
2 Answers

I had exactly the same problem yesterday, and I have found a way to solve it. The "e.preventDefault() stops the window from actually closing so it has time to send the message to the renderer process. When the main process receives a message from the renderer process it then calls the app.quit() method. This in turn call the close event again which continues in an infinite loop. To prevent this you have to check if the event is being called the second time to finally close the app. Hope this helps!

On the Main process:

    const ipc = require('electron').ipcMain;
    let status = 0;

    mainWindow.on('close', function (e) {
    if (status == 0) {
      if (mainWindow) {
        e.preventDefault();
        mainWindow.webContents.send('app-close');
      }
    }
  })

ipc.on('closed', _ => {
  status = 1;
  mainWindow = null;
  if (process.platform !== 'darwin') {
    app.quit();
  }
})

On the renderer process:

const electron = require('electron');
const ipc = electron.ipcRenderer;

ipc.on('app-close', _ => {

        //do something here...

        ipc.send('closed');
    });

I may not understand what yu are trying to do – but if you are trying to send a message from the main process to renderer(s) before quit you can use . . the before-quit event.

Event: 'before-quit'

Returns:

event Event

Emitted before the application starts closing its windows. Calling event.preventDefault() will prevent the default behavior, which is terminating the application.

Related