I have an electron app in which the Ui is built using react js. inside the react js ui other web app is loaded using the webview.
my problem is i need to save the data of the webview app when the electron app is closed.
I want to know how to access the onClose event of the electron app inside the webview app.
Just came upon something similar. You could do something like this.
In the Main process:
const { ipcMain, app, webContents } = require('electron')
app.on('will-quit', event => {
event.preventDefault()
let readyCount = 0
ipcMain.on('ready-to-quit', () => {
readyCount++
if (readyCount === allWebContents.length) {
app.exit()
}
})
const allWebContents = webContents.getAllWebContents()
allWebContents.forEach(contents => contents.send('app-will-quit'))
})
In the Renderer process:
const { ipcRenderer } = require('electron')
ipcRenderer.once('app-will-quit', () => {
// do stuff
ipcRenderer.send('ready-to-quit')
})
Related
in my Game Launcher Electron project I was trying to open a subwindow with a buttonclick, and in there, offer additional features. These features include for example: opening exe files. For this I need node.js so I've tried to create methods for this in the preload script and expose them via contextBridge. These methods work fine in the main BrowserWindow. However, they are not reachable from the subwindow (Uncaught ReferenceError: game is not defined). See the code below:
preload.js
const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;
const { BrowserWindow } = require('electron');
contextBridge.exposeInMainWorld(
'game', {
open: () => {
console.log('test');
},
openAddGamePage: () => {
console.log('test');
}
}
);
renderer.js (script for main window), the exposed methods work fine here.
document.getElementById('openAddGameWindow').addEventListener('click', () => {
const childWindow = window.open('features/addGame/addGamePage.html', '_blank', 'nodeIntegration=yes')
game.open()
game.openAddGamePage()
})
addGame.js (script from addGamePage.html): The methods dont work here
document.getElementById('addGameButton').addEventListener('click', () => {
game.open()
})
I also tried to include the functions directly in the "addGame.js" and enable nodeIntegration when creating the child window, however this did not work either (require is not defined)
Trying to develop a small app using python flask and electron JS, basically i am using electron for only to run Flask Python Script by using (child_process & Spawn) in electron main.js file also using (LoadURL(http://localhost:5000)) instead of using (loadURL(index.html)).
I did close the Browser Window using simple (Window.Close()) function in separate JavaScript file which is linked in the body section, but cant figure out how to MINIMIZE the Browser Window using only JavaScript or Python in the same file linked in body.
Cant use electron for this because i am not using index.html in loadURL.
Appreciate all the help i cant get on this.
You should use a preload script and inter-process Communication
It's as simple as this
// in the preload script
// you can access Electron's renderer process modules here
const { contextBridge, ipcRenderer } = require('electron')
// you should handle the IPC call in the main process
// and call Electron's browserWindow.minimize() function
contextBridge.exposeInMainWorld('minimize', () => ipcRenderer.send('minimize'))
// in the main process, you should have something like this
const {app, BrowserWindow, ipcMain} = require('electron')
const path = require('path')
function createWindow () {
const mainWindow = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
ipcMain.on('minimize', () => {
mainWindow.minimize()
})
mainWindow.loadURL('https://example.com')
}
In your JavaScript file, you can now call window.minimize()
I want to know how to open a web link in the default browser when clicked on a button in an electron app. Can anyone help me?
At the top of your main.js, make sure the following variables are defined:
const ipc = ipcMain;
const { app, BrowserWindow, ipcMain, webContents } = require('electron');
Inside your button onclick function (in the renderer), use the following:
ipc.send('SomeEvent');
Also make sure the following are defined in your renderer
const { ipcRenderer } = require('electron');
const ipc = ipcRenderer;
Then, use the following to open in the external browser (it will open in the user's default)
ipc.on('SomeEvent', ()=>{
require('electron').shell.openExternal('<LINK_HERE>');
})
I have a vue3 app with electron and need to send a variable from the ipcRenderer to my Vue3 page. I cant figure out how to do it especially given vue strips away lots of js. What im trying to do is to save the path of a folder which so far works fine, then display it in the vue3 app either in a span or whatever. I successfully got the value i need to display to the ipcRenderer but cant access it using my vue app.
Vue3 page
<q-btn
id="showpath"
dark
flat
size="xl"
label="show Path"
type="submit"
#click="showpath"
/>
</div>
export default {
name: "Settings",
props: {},
methods: {
loader() {
window.postMessage({
type: "select-dirs",
});
},
showpath() {
const testa = window.postMessage({ type: "pathtf"})
console.log("Vue page says :"+ testa)
},
},
};
</script>
All I get here is "undefined
Preloader script
const { ipcRenderer } = require('electron');
const settings = require('./settings');
process.once('loaded', () => {
window.addEventListener('message', evt => {
if (evt.data.type === 'select-dirs') {
ipcRenderer.send('select-dirs')
}
}),
window.addEventListener('message', evt => {
if (evt.data.type === 'pathtf') {
const pathtf = settings.gettfpath("pathtf")
console.log(pathtf)
}
})
})
The console.log in the preload file works and displays the value, but i cant get that value to my vue3 page.
Any tip? Thank you
I would suggest that you use electron's contextBridge to expose certain methods (send/receive) to the renderer process.
I do not know what your gettfPath method does but if that variable is available to you in the preloadjs file you should be able to expose it as a variable like so:
const {contextBridge} = require("electron");
contextBridge.exposeInMainWorld("electronApi", {
pathtf: settings.gettfPath()
});
With this your path will be exposed to your renderer process as window.electronApi.pathtf
Here are two resources you may find helpful:
How to use preload.js properly in Electron
https://medium.com/swlh/how-to-safely-set-up-an-electron-app-with-vue-and-webpack-556fb491b83 (This one may not be exactly what you are looking for but it has a good explanation / example of how to use ipc with view and electron)
I am currently building an electron app in electron version 5.0.0
I am using electron's power monitor functionality but this can only beaccess from the main electron js file but I need to let a vue component know. I tried using event bus
powerMonitor.on('lock-screen', () => {
console.log("locked")
EventBus.$emit('logout');
})
})
but it looks like evenbus only works within vue components. Anyone got any ideas on how i can just send an even from the electron main js file into a vue component
Okay I finally figured out how its done.
You have to use the ipcRenderer listener wil using webContents to send the event. It should look something like this.
//main.js
powerMonitor.on('unlock-screen', () => {
console.log("unlocked")
win.webContents.send('computer-unlock')
})
//Vue Component
require('electron').ipcRenderer.on('computer-unlock', () => {
console.log("logging in");
_this.computerLocked = false;
})