Reputation: 2997
I want to close the Electron App by js.
"electron": "^13.1.7"
I read those questions carefully:
But none of those work for me.
All the below tests are base on the offical electron-quick-start
index.html
<body>
<button id="close-app">
close
</button>
<script src="./renderer.js"></script>
</body>
main.js
const {BrowserWindow, remote} = require('electron')
...
app.whenReady().then(() => {
...
app.on('activate', function () {
...
document.getElementById("close-app").addEventListener("click", function (e) {
remote.getCurrentWindow().close()
})
})
})
There is just no any effects or errors.
It seems like the code have never been run, I added a console.log('run')
above the addEventListener
and there is nothing been print in the console.
(change nothing of the offical electron-quick-start but only preload.js
and index.html
)
index.html
as same as above
preload.js
const { app } = require('electron');
window.addEventListener('DOMContentLoaded', () => {
document.getElementById("close-app").addEventListener("click", function (e) {
app.quit();
})
})
got Uncaught TypeError: Cannot read property 'quit' of undefined
only
So, how can I close the Electron App by js?
Thanks a lot for anyone help!
Upvotes: 1
Views: 3397
Reputation: 2997
for those who are not using the offical template but a Vue3 webpack based electron.
you have to create the window first in an async function which will return the win
created by BrowserWindow()
main.js
import { BrowserWindow, ipcMain } from 'electron'
async function createWindow() {
// Create the browser window.
const win = new BrowserWindow({
transparent: true,
frame: false,
webPreferences: {
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
enableRemoteModule: true
}
})
if (process.env.WEBPACK_DEV_SERVER_URL) {
await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
if (!process.env.IS_TEST) win.webContents.openDevTools()
}
else {
createProtocol('app')
// Load the index.html when not in development
win.loadURL('app://./index.html')
}
return win;
}
app.on('ready', async () => {
createWindow()
.then(win => {
ipcMain.on('close-app', () => {
win.hide();
});
ipcMain.on('min-app', () => {
win.minimize();
});
});
});
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<span role="control-panel">
<button type="button"
id="min-app"
aria-label="minimize your app">
<i class="mdi mdi-window-minimize text-2xl"></i>
</button>
<button type="button"
id="close-app"
aria-label="close your app">
<i class="mdi mdi-close text-2xl"></i>
</button>
</span>
<script>
// for close/min app
const { ipcRenderer } = require('electron');
document.getElementById('close-app').addEventListener('click', () => {
ipcRenderer.send('close-app');
});
document.getElementById('min-app').addEventListener('click', () => {
ipcRenderer.send('min-app');
});
</script>
</body>
</html>
Upvotes: 2
Reputation: 2464
Electron has modules that only work in the main process like app
and modules that only work in the renderer process like ipcRenderer
and modules that are common and can run in both processes
I recommend reading this article from the Electron docs which explains the process model
Preload scripts contain code that executes in a renderer process before its web content begins loading. These scripts run within the renderer context, but are granted more privileges by having access to Node.js APIs.
Because the app
module is a main process module, if you try to access it from the preload script (renderer process), app
will be undefined
// in preload.js
const { app } = require('electron');
console.log(app); // undefined
Instead, you should use inter-process communication to tell the main process to quit
// in main.js
const { app, ipcMain } = require('electron');
ipcMain.handle('quit-app', () => {
app.quit();
});
// in preload.js
const { ipcRenderer } = require('electron');
window.addEventListener('DOMContentLoaded', () => {
document.getElementById('close-app').addEventListener('click', () => {
ipcRenderer.invoke('quit-app');
});
});
Upvotes: 9