Can't close window in electron - node.js

I have this code in my renderer.js:
const ipcRenderer = require('electron').ipcRenderer;
const remote = require('electron').remote;
function sendForm(event) {
event.preventDefault() // stop the form from submitting
let code = document.getElementById("code").value;
ipcRenderer.send('2FacLogin', {twoFactorCode: code});
// TODO Close Window
var window = remote.getCurrentWindow();
window.close();
}
this is how the window is opened:
const win = new BrowserWindow({
width: 300,
height: 300,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
}
})
Why does the window not close?

Since Electron 10.0.0, the remote module is disabled by default, it must be explicitly enabled when creating a new browser window by adding enableRemoteModule: true to the webPreferences object.
const win = new BrowserWindow({
width: 300,
height: 300,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true
}
})
See: Default Changed: enableRemoteModule defaults to false
BTW, the following statement:
var window = remote.getCurrentWindow();
most certainly triggers an error like:
Uncaught TypeError: Cannot read property 'getCurrentWindow' of undefined
that you can catch yourself by checking the DevTools' console...

Related

how to create a new electron browser window

I am trying to open a new electron window when I press a button, but I can't create it.
Here is the code I used and didn't work:
//creates a new window
//
const createChapterWindow = () => {
// Create the browser window.
print('started window');
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
preload: path.join(__dirname, 'preload.js'),
},
});
print('step 1 finished')
// and load the index.html of the app.
mainWindow.loadFile(path.join(__dirname, 'chapter.html'));
// Open the DevTools.
mainWindow.webContents.openDevTools();
print('finished window')
};
//calls browser window
createChapterWindow();
}
function print(text){
console.log(`\n\n\n${text}\n\n\n`)
}
I copied most of this code from the part where I create the main window, so that might be the issue.

Electron | TypeError: "x" is not a constructor

I have a simple electron app that opens a browser window to a url of a webpage.
I import my stuff using
const { BrowserWindow, app, MessageChannelMain } = require('electron');
I create my window on app.on("ready") using window = new BrowserWindow({ ... }); and everything works fine.
When I try to create a MessageChannelMain using const {port1, port2} = new MessageChannelMain();, I get the error:
TypeError: MessageChannelMain is not a constructor.
Full code:
function init_window(){
if ( mainWindow == null ) {
mainWindow = create_window();
load_window(); // calls mainWindow.loadURL(myURL);
const {port1, port2} = new MessageChannelMain();
port2.postMessage({ test: 21 })
port2.on('message', (event) => {
console.log('from renderer main world:', event.data)
});
port2.start();
mainWindow.webContents.postMessage('main-world-port', null, [port1])
mainWindow.on('closed', function(event) {
mainWindow = null;
});
mainWindow.webContents.on("did-fail-load", function(event) {
})
}
}
function create_window() {
return new BrowserWindow({
width: 1200,
height: 800,
darkTheme: true,
webPreferences: {
contextIsolation: true,
preload: path.join(__dirname, 'preload.js'),
},
});
}
When I console.log(MessageChannelMain); I get undefined.
At the same time, I get other errors when I try to use some electron stuff on the preload script:
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld(
'electron',
{
doThing: () => ipcRenderer.send('do-a-thing')
}
)
Here I am getting TypeError: Cannot read property 'exposeInMainWorld' of undefined

Electron.js | Remove new window frame

I'm using an index.html including an iframe. When a page is opened in a new tab with CTRL + Click keys, the properties I defined for BrowserWindow are not applied.
I want to remove the frame of the opened new tab. How can I do it?
const path = require('path')
const {app, BrowserWindow, Menu} = require('electron')
function createWindow() {
const win = new BrowserWindow({
width: 1000,
height: 700,
frame: false,
show: false,
})
win.loadFile('index.html')
win.once('ready-to-show', () => { win.show() });
}
const menu = Menu.buildFromTemplate([])
Menu.setApplicationMenu(menu)
app.whenReady().then(() => { createWindow() })
Windows opened via links don't inherit their parents options, instead, you have to register a window open handler and set the options manually:
win.webContents.setWindowOpenHandler(({ url }) => {
return {
action: 'allow',
overrideBrowserWindowOptions: { // These options will be applied to the new BrowserWindow
frame: false,
// other BrowserWindow settings
}
}
}
On the documentation: https://www.electronjs.org/docs/latest/api/window-open#native-window-example

Electron window.require is not a function even with nodeIntegration set to true

I've been experiencing some issues with an Electron + Create React App app I'm making. It's an offline app for cost calculation, I need to persist a couple user settings, for this I used https://github.com/sindresorhus/electron-store. Like with most electron's modules, I have to import it as:
const Store = window.require("electron-store");
To avoid webpack's conflicts. By searching I found that for most people setting nodeIntegration: true when creating electron's BrowserWindow would avoid the problem, but it's not my case, I keep getting the same error.
What I've already tried:
Using plain require: It results in TypeError: fs.existsSync is not a function, and in console: Can't resolve 'worker_threads' in '...\node_modules\write-file-atomic'
Use a module to override webpack config: I used craco to set target to electron-renderer. It results in a blank page when I launch the app, with an error in devtools telling ReferenceError: require is not defined
Additional info is that I'm not using typescript but plain js so using "declare global" and such won't work
My public/electron.js file:
const electron = require("electron");
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
const path = require("path");
const isDev = require("electron-is-dev");
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 900,
height: 680,
webPreferences: {
nodeIntegration: true
}
});
mainWindow.loadURL(
isDev
? "http://localhost:3000"
: `file://${path.join(__dirname, "../build/index.html")}`
);
mainWindow.on("closed", () => (mainWindow = null));
if (!isDev) mainWindow.setMenu(null);
}
app.on("ready", createWindow);
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});
electron.app.allowRendererProcessReuse = true;
app.on("activate", () => {
if (mainWindow === null) {
createWindow();
}
});
You have tu create a preoload script on electron.
Create a file named preload.js on the directory where you have de electron main script, Put this code on it:
window.require = require;
Go to your electron main script and type this in the code where you create the window:
win = new BrowserWindow({
width: 1280,
height: 720,
webPreferences: {
nodeIntegration: false,
preload: __dirname + '/preload.js'
},
})
With this you will preload the script before all, this fixed the problem for me, I hope also for you.
Electron 12 changed the default setting of contextIsolation for webPreferences, as documented in their breaking changes for Electron 12. Setting it to false will allow you access to require() again, as per their notes:
In Electron 12, contextIsolation will be enabled by default. To restore the previous behavior, contextIsolation: false must be specified in WebPreferences.
We recommend having contextIsolation enabled for the security of your application.
Another implication is that require() cannot be used in the renderer process unless nodeIntegration is true and contextIsolation is false.
mainWindow = new BrowserWindow({
width: 900,
height: 680,
webPreferences: {
contextIsolation: false,
nodeIntegration: true
}
}

Electron.remote is undefined

I have trouble with using Electron. As you can see the title, when i load remote module, it saids it is undefined. This is the code of entry js:
const electron = require('electron');
const { app, BrowserWindow, Tray, remote, ipcMain } = electron;
function initApp() { ... }
app.on('ready', () => {
initApp();
console.log(electron); // object, but no remote inside
console.log(electron.remote); // undefined
console.log(remote); // undefined
});
and i tried to follow official doc here: http://electron.atom.io/docs/api/remote/
with
const { remote } = electron;
const { BrowserWindow } = remote;
let win = new BrowserWindow({width: 800, height: 600}); // error! BrowserWindow is not a constructor blabla
...
remote.getCurrentWindow().focus();
i don't know what am i missing. any advice will very appreciate.
Update 2020, since this answer still appears at the top. For the original answer to work in current versions of Electron, you need to set enableRemoteModule when creating the window in your main process.
const myWindow = new BrowserWindow({
webPreferences: {
enableRemoteModule: true
}
});
Original answer:
remote is needed only to require other modules from inside a render process. In the main process you just get your modules directly from require('electron'). Which it looks like is done in the example just with remote unnecessarily added.
Render process:
const { remote } = require('electron');
const { BrowserWindow } = remote;
Main process:
const { BrowserWindow } = require('electron');
In electron 10.0.0, remoteModule is set false by default. So, if you want to use const {BrowserWindow, dialog } = require('electron').remote; in JavaScript file, then you must set enableRemoteModule as true in webPreferences.
const w = new BrowserWindow({
webPreferences: {
enableRemoteModule: true
}
});
link: https://github.com/electron/electron/blob/master/docs/breaking-changes.md#default-changed-enableremotemodule-defaults-to-false
The remote module was deprecated in Electron 12, and will be removed in Electron 14. It is replaced by the #electron/remote module.
// Deprecated in Electron 12:
const { BrowserWindow } = require('electron').remote
// Replace with:
const { BrowserWindow } = require('#electron/remote')
// In the main process:
require('#electron/remote/main').initialize()
remote becomes undefined sometimes in electron all you have to do is to go to your main.js and add the following object while creating a window under webPreference set enableRemoteModule: true as shown bellow then your problem will be solved
win = new BrowserWindow({
width: 700,
height: 600,
hasShadow: true,
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true,
},
});
i enabled remote module, still getting
index.html:43 Uncaught TypeError: Cannot read properties of undefined (reading 'getCurrentWindow')
for
const remote = require('electron').remote;
(or)
const { remote } = require('electron');
while using
remote.getCurrentWindow().close();
i did add
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true,
}

Resources