I want to know how can I add about button in my electron app that opens popup with software details? something like this:
Code
This is how currently my index.js looks like:
const { app, BrowserWindow, Menu } = require('electron');
const isDevMode = require('electron-is-dev');
const { CapacitorSplashScreen, configCapacitor } = require('#capacitor/electron');
const path = require('path');
// Place holders for our windows so they don't get garbage collected.
let mainWindow = null;
// Placeholder for SplashScreen ref
let splashScreen = null;
//Change this if you do not wish to have a splash screen
let useSplashScreen = true;
// Create simple menu for easy devtools access, and for demo
const menuTemplateDev = [
{
label: 'Options',
submenu: [
{
label: 'Open Dev Tools',
accelerator: "CmdOrCtrl+D",
click() {
mainWindow.openDevTools();
},
},
],
},
{
label: 'Help',
submenu: [
{
label: 'Support',
accelerator: "CmdOrCtrl+H",
click: async () => {
const { shell } = require('electron');
await shell.openExternal('https://example.com/contact-us');
}
},
{ type: 'separator' },
{
label: 'Quit!',
accelerator: "CmdOrCtrl+Q",
click() {
app.quit();
}
}
]
}
];
const menuTemplateProd = [
{
label: 'Help',
submenu: [
{
label: 'Support',
accelerator: "CmdOrCtrl+H",
click: async () => {
const { shell } = require('electron')
await shell.openExternal('https://example.com/contact-us')
}
},
{ type: 'separator' },
{
label: 'Quit!',
accelerator: "CmdOrCtrl+Q",
click() {
app.quit();
}
}
]
}
];
async function createWindow () {
// Define our main window size
mainWindow = new BrowserWindow({
height: 920,
width: 1600,
show: false,
// icon: __dirname + '/Icon/Icon.icns',
webPreferences: {
nodeIntegration: true,
preload: path.join(__dirname, 'node_modules', '#capacitor', 'electron', 'dist', 'electron-bridge.js')
}
});
mainWindow.setIcon(path.join(__dirname, '/splash_assets/logo.png'));
configCapacitor(mainWindow);
if (isDevMode) {
// Set our above template to the Menu Object if we are in development mode, dont want users having the devtools.
Menu.setApplicationMenu(Menu.buildFromTemplate(menuTemplateDev));
// If we are developers we might as well open the devtools by default.
mainWindow.webContents.openDevTools();
} else {
Menu.setApplicationMenu(Menu.buildFromTemplate(menuTemplateProd));
}
if(useSplashScreen) {
splashScreen = new CapacitorSplashScreen(mainWindow);
splashScreen.init();
} else {
mainWindow.loadURL(`file://${__dirname}/app/index.html`);
mainWindow.webContents.on('dom-ready', () => {
mainWindow.show();
});
}
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some Electron APIs can only be used after this event occurs.
app.on('ready', createWindow);
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow();
}
});
// Define any IPC or other custom functionality below here
Any suggestions?
SOLVED
I've added new window function and new index file. And changed my index.js to the following code:
const { app, BrowserWindow, Menu } = require('electron');
const isDevMode = require('electron-is-dev');
const { CapacitorSplashScreen, configCapacitor } = require('#capacitor/electron');
const path = require('path');
// Place holders for our windows so they don't get garbage collected.
let mainWindow = null;
let childWindow = null; // <---- ADDED
// Placeholder for SplashScreen ref
let splashScreen = null;
//Change this if you do not wish to have a splash screen
let useSplashScreen = true;
// Create simple menu for easy devtools access, and for demo
const menuTemplateDev = [
{
label: 'Options',
submenu: [
{
label: 'Open Dev Tools',
accelerator: "CmdOrCtrl+D",
click() {
mainWindow.openDevTools();
},
},
],
},
{
label: 'Help',
submenu: [
{ // <---- ADDED
label: 'About', // <---- ADDED
accelerator: "F1", // <---- ADDED
click: async () => { // <---- ADDED
createAboutWindow(); // <---- ADDED
} // <---- ADDED
}, // <---- ADDED
{
label: 'Support',
accelerator: "CmdOrCtrl+H",
click: async () => {
const { shell } = require('electron');
await shell.openExternal('https://example.com/contact-us');
}
},
{ type: 'separator' },
{
label: 'Quit!',
accelerator: "CmdOrCtrl+Q",
click() {
app.quit();
}
}
]
}
];
const menuTemplateProd = [
{
label: 'Help',
submenu: [
{ // <---- ADDED
label: 'About', // <---- ADDED
accelerator: "F1", // <---- ADDED
click: async () => { // <---- ADDED
createAboutWindow(); // <---- ADDED
} // <---- ADDED
}, // <---- ADDED
{
label: 'Support',
accelerator: "CmdOrCtrl+H",
click: async () => {
const { shell } = require('electron')
await shell.openExternal('https://example.com/contact-us')
}
},
{ type: 'separator' },
{
label: 'Quit!',
accelerator: "CmdOrCtrl+Q",
click() {
app.quit();
}
}
]
}
];
async function createWindow () {
// Define our main window size
mainWindow = new BrowserWindow({
height: 920,
width: 1600,
show: false,
// icon: __dirname + '/Icon/Icon.icns',
webPreferences: {
nodeIntegration: true,
preload: path.join(__dirname, 'node_modules', '#capacitor', 'electron', 'dist', 'electron-bridge.js')
}
});
mainWindow.setIcon(path.join(__dirname, '/splash_assets/logo.png'));
configCapacitor(mainWindow);
if (isDevMode) {
// Set our above template to the Menu Object if we are in development mode, dont want users having the devtools.
Menu.setApplicationMenu(Menu.buildFromTemplate(menuTemplateDev));
// If we are developers we might as well open the devtools by default.
mainWindow.webContents.openDevTools();
} else {
Menu.setApplicationMenu(Menu.buildFromTemplate(menuTemplateProd));
}
if(useSplashScreen) {
splashScreen = new CapacitorSplashScreen(mainWindow);
splashScreen.init();
} else {
mainWindow.loadURL(`file://${__dirname}/app/index.html`);
mainWindow.webContents.on('dom-ready', () => {
mainWindow.show();
});
}
}
async function createAboutWindow () { // <---- ADDED
// Define our main window size
childWindow = new BrowserWindow({ // <---- ADDED
height: 400, // <---- ADDED
width: 600, // <---- ADDED
show: false, // <---- ADDED
minimizable: false, // <---- ADDED
maximizable: false, // <---- ADDED
parent: mainWindow, // <---- ADDED
// icon: __dirname + '/Icon/Icon.icns', // <---- ADDED
webPreferences: { // <---- ADDED
nodeIntegration: true, // <---- ADDED
preload: path.join(__dirname, 'node_modules', '#capacitor', 'electron', 'dist', 'electron-bridge.js') // <---- ADDED
} // <---- ADDED
}); // <---- ADDED
childWindow.setIcon(path.join(__dirname, '/splash_assets/logo.png')); // <---- ADDED
configCapacitor(childWindow); // <---- ADDED
childWindow.removeMenu(); // <---- ADDED
childWindow.loadURL(`file://${__dirname}/index_child.html`); // <---- ADDED
childWindow.webContents.on('dom-ready', () => { // <---- ADDED
childWindow.show(); // <---- ADDED
}); // <---- ADDED
} // <---- ADDED
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some Electron APIs can only be used after this event occurs.
app.on('ready', createWindow);
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow();
}
if (childWindow === null) { // <---- ADDED
createAboutWindow(); // <---- ADDED
} // <---- ADDED
});
// Define any IPC or other custom functionality below here
Final result
Hope it can help those in need :) .
Related
I'm new to Electron and I joined an existing project. I'm trying to add an image before the main screen of the app that will last 5 seconds. At first, I tried it with useState and setTimeone but I've realized I'm in the wrong place of the code.
After reading all kinds of solutions, and running the app - I now need your help.
This is some of the code in my main.ts file:
mainWindow = new BrowserWindow({
show: false,
width: 521,
height: 712,
icon: getAssetPath('icon.png'),
webPreferences: {
nodeIntegration: true,
contextIsolation: true,
preload: app.isPackaged
? path.join(__dirname, 'preload.+212 662-122618 js')
: path.join(__dirname, '../../.erb/dll/preload.js'),
},
});
mainWindow.loadURL(resolveHtmlPath('index.html'));
mainWindow.on('ready-to-show', () => {
if (!mainWindow) {
throw new Error('"mainWindow" is not defined');
}
if (process.env.START_MINIMIZED) {
mainWindow.minimize();
} else {
mainWindow.show();
}
});
mainWindow.on('closed', () => {
mainWindow = null;
});
const menuBuilder = new MenuBuilder(mainWindow);
menuBuilder.buildMenu();
// Open urls in the user's browser
mainWindow.webContents.setWindowOpenHandler((edata) => {
shell.openExternal(edata.url);
return { action: 'deny' };
});
// Remove this if your app does not use auto updates
// eslint-disable-next-line
new AppUpdater();
};
/**
* Add event listeners...
*/
app.on('window-all-closed', () => {
// Respect the OSX convention of having the application in memory even
// after all windows have been closed
if (process.platform !== 'darwin') {
app.quit();
}
});
app
.whenReady()
.then(() => {
createWindow();
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) createWindow();
});
})
.catch(console.log);
I installed electron-context-menu using the command
npm i electron-context-menu
And then I used the code that is on this site
const {app, BrowserWindow} = require('electron');
const contextMenu = require('electron-context-menu');
contextMenu({
showSaveImageAs: true
});
let mainWindow;
(async () => {
await app.whenReady();
mainWindow = new BrowserWindow({
webPreferences: {
spellcheck: true
}
});
})();
But when I right click on the window, the ContextMenu with the items doesn't appear.
A white window only appears:
What should I do to make ContextMeu appear?
You won't need a lib for do this (And IMO you Shouldn't). The electron API already give to you a context-menu ready to use.
If you already use contextBridge just follow the electron site steps.
main.ts
// ...
ipcMain.on('show-context-menu', (event) => {
const template = [
{
label: 'Menu Item 1',
click: () => { event.sender.send('context-menu-command', 'menu-item-1') }
},
{ type: 'separator' },
{ label: 'Menu Item 2', type: 'checkbox', checked: true }
]
const menu = Menu.buildFromTemplate(template)
menu.popup(BrowserWindow.fromWebContents(event.sender))
})
renderer.ts
window.addEventListener('contextmenu', (e) => {
e.preventDefault()
ipcRenderer.send('show-context-menu')
})
ipcRenderer.on('context-menu-command', (e, command) => {
// What it will do when this options is click it
})
You can create a preload for each action too if you want
Also, if you want the browser default contextMenu, here comes a example.
Running into a really strange quirk and can't figure out what I'm doing wrong:
init.js
const os = require('os');
const path = require('path');
const { app, BrowserView, BrowserWindow, ipcMain } = require('electron');
let win = null;
// Init function
const init = function() {
return new Promise((resolve, reject) => {
try {
// BrowserWindow config
const config = {
backgroundColor: '#1d1e20',
show: false,
webPreferences: {
contextIsolation: true,
enableRemoteModule: false,
preload: path.join(__dirname, 'preload.js'),
}
};
// Make BrowserWindow frameless (win) or hide titlebar (mac)
if ('win32' === os.platform()) {
config.frame = false;
} else if ('darwin' === os.platform()) {
config.titleBarStyle = 'hidden';
}
// Create BrowserWindow
win = new BrowserWindow(config);
// Add listener for BrowserWindow 'ready-to-show' event
win.once('ready-to-show', () => {
// Set traffic light position (mac)
win.setTrafficLightPosition({ x: 10, y: 27 });
// Show browser window
win.show();
// Open DevTools
win.openDevTools({ mode: "detach" });
resolve();
});
// Load app html
win.loadFile('./app.html').then(() => {
// loaded
}).catch((err) => {
reject(err);
});
} catch (err) {
reject(err);
}
});
};
// Add browser view
const addView = function(url) {
return new Promise((resolve, reject) => {
try {
// Get window size
const bounds = win.getSize();
// Create BrowserView
const view = new BrowserView({
backgroundColor: "#ffffff",
webPreferences: {
contextIsolation: true,
enableRemoteModule: false,
//preload: path.join(__dirname, 'preload.js'),
}
});
view.setBounds({
height: 375,
width: 375,
x: 0,
// Set "y" coordinate to 0
// (should be relative to BrowserWindow 0, 0)
y: 0
// Set "y" coordinate to a
// negative integer
//y: -200
// Instead, set "y" to inverse of
// BrowserWindow height
//y: bounds[1] * -1
});
// Load file
view.webContents.loadFile('./new.html').then(() => {
// Add to BrowserWindow
win.addBrowserView(view);
// Open DevTools
view.webContents.openDevTools({ mode: "detach" });
resolve();
}).catch((err) => {
reject(err);
});
} catch (err) {
reject(err);
}
});
};
// init when ready
app.whenReady().then(() => {
init().then(() => {
addView().then(() => {
console.log("Everything should be working right");
}).catch((err) => {
console.log("Error loading BrowserView");
console.error(err);
});
}).catch((err) => {
console.log("Error loading BrowserWindow");
console.error(err);
});
});
Expected result: new BrowserView stacked squarely on top of BrowserWindow at defined width and height, positioned at 0, 0.
Actual result: new BrowserView displayed below the fold, with its "y" coordinate relative to bottom of BrowserWindow. To get BrowserView to show at BrowserWindow 0, 0, must set BrowserView "y" coordinate to (BrowserWindowHeight * -1)
Edit: P.S.
package.json
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "init.js",
"scripts": {
"start": "electron ."
},
"author": "",
"license": "",
"devDependencies": {
"electron": "^12.0.1"
}
}
preload.js
(no contents)
app.html
(no contents)
app.js
(no contents)
app.css
(no contents)
new.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test</title>
<style>
html {
margin: 0;
padding: 0;
}
body {
background: #ffffff;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
Update #1
Delay call to view.setBounds() by moving inside promise callback of view.loadURL(). No change.
Update #2
Further delay call to view.setBounds() by additionally wrapping in setTimeout() with delay of 1000ms. No change.
Update #3
By adding the following, the BrowserView does snap to correct 0, 0 position within parent BrowserWindow, but only upon resize event:
win.on('will-resize', (event, newBounds) => {
win.getBrowserViews().forEach((view) => {
view.setBounds({
height: newBounds.height,
width: newBounds.width,
x: 0,
y: 0
});
});
});
Update #4
Replaced BrowserWindow.loadFile() and BrowserView.loadFile() calls with .loadURL() using google.com and stackoverflow.com, respectively, to eliminate the possibility of it being something to do with my local files. No change.
Update #5
By modifying the init.js as follows, it works as expected, however it's not pretty as it "snaps" into position. (Edit: to clarify, BrowserView defined with solid background which I expect to be displayed until .loadURL() completes, unless I've somehow misunderstood the purpose of the backgroundColor property) (Edit: I've just realized that backgroundColor is not a valid property of the BrowserView)
const os = require('os');
const path = require('path');
const { app, BrowserView, BrowserWindow, ipcMain } = require('electron');
let win = null;
// Init function
const init = function() {
return new Promise((resolve, reject) => {
try {
// BrowserWindow config
const config = {
backgroundColor: '#1d1e20',
show: false,
webPreferences: {
contextIsolation: true,
enableRemoteModule: false,
preload: path.join(__dirname, 'preload.js'),
}
};
// Make BrowserWindow frameless (win) or hide titlebar (mac)
if ('win32' === os.platform()) {
config.frame = false;
} else if ('darwin' === os.platform()) {
config.titleBarStyle = 'hidden';
}
// Create BrowserWindow
win = new BrowserWindow(config);
// Add listener for BrowserWindow 'ready-to-show' event
win.once('ready-to-show', () => {
// Set traffic light position (mac)
win.setTrafficLightPosition({ x: 10, y: 27 });
// Show browser window
win.show();
// Open DevTools
win.openDevTools({ mode: "detach" });
});
// Add listener for BrowserWindow 'show' event
win.once('show', () => {
resolve();
});
win.on('will-resize', (event, newBounds) => {
win.getBrowserViews().forEach((view) => {
view.setBounds({ height: newBounds.height, width: newBounds.width, x: 0, y: 0 });
});
});
// Load app html
win.loadURL("https://google.com").then(() => {
// loaded
}).catch((err) => {
reject(err);
});
} catch (err) {
reject(err);
}
});
};
// Add browser view
const addView = function(url) {
return new Promise((resolve, reject) => {
try {
// Create BrowserView
const view = new BrowserView({
backgroundColor: "#edeef0",
webPreferences: {
contextIsolation: true,
enableRemoteModule: false
}
});
// Load file
view.webContents.loadURL('https://stackoverflow.com').then(() => {
setTimeout(() => {
// Get window size
const bounds = win.getSize();
// Set BrowserView bounds
view.setBounds({ height: bounds[1], width: bounds[0], x: 0, y: 0 });
}, 1);
// Add to BrowserWindow
win.addBrowserView(view);
// Open DevTools
view.webContents.openDevTools({ mode: "detach" });
resolve();
}).catch((err) => {
reject(err);
});
} catch (err) {
reject(err);
}
});
};
// init when ready
app.whenReady().then(() => {
init().then(() => {
addView().then(() => {
console.log("Everything should be working right");
}).catch((err) => {
console.log("Error loading BrowserView");
console.error(err);
});
}).catch((err) => {
console.log("Error loading BrowserWindow");
console.error(err);
});
});
Update #6
I've come to the conclusion that in current version of Electron (12.0.1), a BrowserView is rendered with equivalent of CSS position: relative, but almost immediately thereafter, changed to equivalent of CSS position: absolute. Calling BrowserView.setBounds({ x: 0, y: 0 }) immediately upon creation of the BrowserView, the BrowserView is actually displayed at { x: 0, y: (BrowserWindow height) }, whereas calling BrowserView.setBounds({ x: 0, y: 0 }) within a setTimeout() after a 1ms delay, the BrowserView is actually displayed at { x: 0, y: 0}. I'm not sure why this is, but it seems the fix (tested only on macOS 10.14.6) is as follows:
const view = new BrowserView(...);
const size = win.getSize();
view.setBounds({ height: size[1], width: size[0], x: 0, y: size[0] * -1 });
and, on the BrowserWindow:
win.on('will-resize', (event, newBounds) => {
win.getBrowserViews().forEach((view) => {
view.setBounds({ height: newBounds.height, width: newBounds.width, x: 0, y: 0 });
});
});
Update #7
This still feels very unwieldy and I suspect this is not the intended behavior and I still may be doing something wrong. I'm going to leave this question open and hope that someone has a better solution than what I've found.
Update #8
Finally figured out that it was my sloppy implementation. After RTFM, adding some promises, and doing things in the proper order, there is no problem.
For educational purposes, I broke it down and reversed my steps to find the source of the problem so I know for future reference. For anyone else who may ever find this and have the same problem -- you must call BrowserWindow.addBrowserView() BEFORE calling BrowserView.setBounds(). That was the problem.
I was calling BrowserView.setBounds() immediately after creating the BrowserView -- at which point it was not added to the BrowserWindow yet, hence why the coords were off. I didn't call BrowserWindow.addBrowserView() until BrowserView.loadFile() resolved.
Must call BrowserWindow.addBrowserView() BEFORE calling BrowserView.setBounds() -- (see Update #8)
I'm building an app on electron and now I'm trying to create a simple file.
Here's the JS:
const app = require("electron").remote;
var dialog = app.dialog;
var fs = require("fs");
document.getElementById('save_project').onclick=() => {
dialog.showSaveDialog((filename) => {
if(filename === undefined){
console.log("You didnt save the file");
return;
};
var content = "hello there";
fs.writeFile(filename, content, (err) => {
if(err) console.log(err);
alert("The file has been successfully saved.")
})
});
};
This window will open as supposed:
Then, I wrote for instance: "hello.txt" on the name input and clicked save.
There's no log written on the console neither a file written in the directory
Edit:
with this js, happens the same ():
const fs = require("fs");
const {dialog} = require("electron").remote;
document.getElementById("save_project").addEventListener("click", () => {
dialog.showSaveDialog((filename) => {
if(filename === undefined){
console.log("nop");
return;
}
fs.writeFile(filename, content, (err) => {
if(err){
console.log(err);
return;
}
alert("file created");
});
});
}, false);
Edited:
Here's the createWindow()
function createWindow () {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 1920,
height: 1080,
webPreferences: {
preload: path.join(__dirname, "preload.js"),
nodeIntegration: true
},
});
const childWindow = new BrowserWindow ({ width: 1600, height: 800, parent: mainWindow, modal: true, show : false});
// and load the index.html of the app.
mainWindow.loadFile("index.html");
childWindow.loadFile("welcome.html");
childWindow.once("ready-to-show", () => {
childWindow.show();
});
// Open the DevTools.
mainWindow.webContents.openDevTools();
}
Basically, from what i understood, "dialog.showSaveDialog((filename).." this was kinda blocking... i fixed by using:
const {dialog} = require("electron").remote;
let filename = dialog.showSaveDialogSync()
if(filename === undefined){
console.log("filename undefined");
return;
}else{
console.log(filename)
saveAsToFile(filename, ...);
}
I'm trying to make my electron app auto-updatable, and after searching on google I found nice guide that works. The only problem is that I want to create a button for when update is downloaded so that the user can decide when he wants to update and restart the app. So far I was able to put this code together
renderer.js
const electron = require('electron')
const ipcRenderer = electron.ipcRenderer
let lastMsgId = 0
window.quitAndInstall = function () {
electron.remote.autoUpdater.quitAndInstall()
}
ipcRenderer.on('console', (event, consoleMsg) => {
console.log(consoleMsg)
})
ipcRenderer.on('message', (event, data) => {
showMessage(data.msg, data.hide, data.replaceAll)
})
function showMessage(message, hide = true, replaceAll = false) {
const messagesContainer = document.querySelector('.messages-container')
const msgId = lastMsgId++ + 1
const msgTemplate = `<div id="${msgId}" class="alert alert-info alert-info-message animated fadeIn">${message}</div>`
if (replaceAll) {
messagesContainer.innerHTML = msgTemplate
} else {
messagesContainer.insertAdjacentHTML('afterbegin', msgTemplate)
}
if (hide) {
setTimeout(() => {
const msgEl = document.getElementById(msgId)
msgEl.classList.remove('fadeIn')
msgEl.classList.add('fadeOut')
}, 4000)
}
}
and this is my index.js where messages are storred
const electron = require('electron');
const {autoUpdater} = require('electron-updater');
const log = require('electron-log');
const appVersion = require('./package.json').version
// configure logging
autoUpdater.logger = log;
autoUpdater.logger.transports.file.level = 'info';
log.info('App starting...');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 1020,
height: 800,
});
mainWindow.loadURL('file://' +__dirname + '/public/index.html');
// Open the DevTools.
//mainWindow.webContents.openDevTools();
mainWindow.on('closed', function() {
mainWindow = null;
});
}
app.on('ready', createWindow);
// Quit when all windows are closed.
app.on('window-all-closed', function() {
app.quit();
});
app.on('activate', function() {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow();
}
});
//-------------------------------------------------------------------
// Auto updates
//-------------------------------------------------------------------
const sendStatusToWindow = (text) => {
log.info(text);
if (mainWindow) {
mainWindow.webContents.send('console', `App version: ${appVersion}`)
mainWindow.webContents.send('message', { msg: `App version: ${appVersion}` })
}
};
autoUpdater.on('error', (ev, err) => {
mainWindow.webContents.send('message', { msg: `Error: ${err}` })
})
autoUpdater.once('checking-for-update', (ev, err) => {
mainWindow.webContents.send('message', { msg: 'Checking for updates' })
})
autoUpdater.once('update-available', (ev, err) => {
mainWindow.webContents.send('message', { msg: 'Update available. Downloading ⌛️', hide: false })
})
autoUpdater.once('update-not-available', (ev, err) => {
mainWindow.webContents.send('message', { msg: 'Update not available' })
})
autoUpdater.once('update-downloaded', (ev, err) => {
const msg = 'Update downloaded - <button onclick="quitAndInstall()">Restart</button>'
mainWindow.webContents.send('message', { msg, hide: false, replaceAll: true })
})
autoUpdater.checkForUpdates()
As you can see I added a button to call for function but it doesnt work. When I press the button nothing happens. If I remove button and just say auto.updater.quitAndInstall() it works. It auto close window and install new version. What am I missing?
I think it's that electron.remote.autoUpdater.quitAndInstall() doesn't work when run in the renderer.
In the docs it doesn't say anything against running it in the renderer process but I think sending a message back to the main process to run the quitAndInstall function would work.
Inside of the quitAndInstall function put this instead:
ipcRenderer.send('asynchronous-message', 'quitAndInstall');
Then in the main process put:
electron.ipcMain.on('asynchronous-message', function (evt, message) {
if (message == 'quitAndInstall') {
autoUpdater.quitAndInstall();
}
});