Electron:如何在 2021 年通过 js 关闭应用程序?
Electron :how to close app via js in 2021?
我想用js关闭Electron App
"electron": "^13.1.7"
我仔细看了那些问题:
- Atom Electron - 用 javascript 关闭 window
- How to close electron app via javascript?
但是 none 对我有用。
以下所有测试均基于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()
})
})
})
没有任何影响或错误。
好像代码从来没有运行,我在addEventListener
上面加了一个console.log('run')
,控制台也没有打印出来
根据document,我得到了这些代码:
(不更改 the offical electron-quick-start,仅更改 preload.js
和 index.html
)
index.html
同上
preload.js
const { app } = require('electron');
window.addEventListener('DOMContentLoaded', () => {
document.getElementById("close-app").addEventListener("click", function (e) {
app.quit();
})
})
只有Uncaught TypeError: Cannot read property 'quit' of undefined
那么,如何通过js关闭Electron App呢?
非常感谢任何人的帮助!
Electron 有只在主进程中工作的模块,如 app
和只在渲染进程中工作的模块,如 ipcRenderer
和通用的模块,可以在两者中 运行进程
我建议阅读解释流程模型的 Electron 文档 this article
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.
因为app
模块是一个主进程模块,如果你试图从预加载脚本(渲染进程)访问它,app
将是未定义的
// in preload.js
const { app } = require('electron');
console.log(app); // undefined
相反,您应该使用进程间通信来告诉主进程退出
// 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');
});
});
对于那些没有使用官方模板而是使用基于 Vue3 webpack 的 electron 的人。
您必须先在异步函数中创建 window,这将 return BrowserWindow()
创建的 win
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>
我想用js关闭Electron App
"electron": "^13.1.7"
我仔细看了那些问题:
- Atom Electron - 用 javascript 关闭 window
- How to close electron app via javascript?
但是 none 对我有用。
以下所有测试均基于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()
})
})
})
没有任何影响或错误。
好像代码从来没有运行,我在addEventListener
上面加了一个console.log('run')
,控制台也没有打印出来
根据document,我得到了这些代码:
(不更改 the offical electron-quick-start,仅更改 preload.js
和 index.html
)
index.html
同上
preload.js
const { app } = require('electron');
window.addEventListener('DOMContentLoaded', () => {
document.getElementById("close-app").addEventListener("click", function (e) {
app.quit();
})
})
只有Uncaught TypeError: Cannot read property 'quit' of undefined
那么,如何通过js关闭Electron App呢?
非常感谢任何人的帮助!
Electron 有只在主进程中工作的模块,如 app
和只在渲染进程中工作的模块,如 ipcRenderer
和通用的模块,可以在两者中 运行进程
我建议阅读解释流程模型的 Electron 文档 this article
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.
因为app
模块是一个主进程模块,如果你试图从预加载脚本(渲染进程)访问它,app
将是未定义的
// in preload.js
const { app } = require('electron');
console.log(app); // undefined
相反,您应该使用进程间通信来告诉主进程退出
// 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');
});
});
对于那些没有使用官方模板而是使用基于 Vue3 webpack 的 electron 的人。
您必须先在异步函数中创建 window,这将 return BrowserWindow()
win
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>