I'm trying to receive the name of a new file from the front-end using ipcRenderer, sending it to electron and using ipcMain to listen to this event and load a new view for the window. However, the loadURL re-renders the same view. I've checked and made sure that the correct name is sent back back and that the path to the file is correct.
Here is a code snippet of the two method calls:
let win
const createWindow = () => {
win = new BrowserWindow({width: 800, height: 600})
win.loadURL(url.format({
pathname: path.join(__dirname, '/src/index.ejs'),
protocol: 'file:',
slashes: true
}));
};
app.on('ready', createWindow);
ipcMain.on('redirectToView', (event, metadata) => {
const pathToView = `${__dirname}/src/views/${metadata.viewName}.ejs`;
const URL = url.format({
pathname: pathToView,
protocol: 'file:',
slashes: true
})
win.loadURL(URL);
})
Related
I am trying to execute a binary file in linux when an electron app is started. In development mode, everything is working properly, but when I build the app binary file (which is part of the app) is not executed.
Here is the code where I`m executing the binary file:
const { spawn, exec } = require('child_process');
const startServer = () => {
const ls = exec('./binary');
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
};
function createWindow() {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
icon: './electronJs.png',
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
},
});
mainWindow.loadURL(
url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true,
})
);
}
app.whenReady().then(() => {
createWindow();
startServer();
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
Directory path ./ is relative to generated executable file once packaged.
You should use __dirname to fully qualify your binary path and make it relative to the calling file.
const path = require('path')
const myexefilepath = path.join(__dirname, 'binary')
...
const ls = exec(myexefilepath);
If you use asar file format to package your app, previous solution won't work.
Your options then are:
Copy binary to the same folder where the generated executable file is.
Use app.getPath( name ) to get a path to a special directory where you can put your binary. My choice being name: userData
This error occurs seldom in the app when it loads (Not all the time). The index.js is the main file ,selected in package.json, and the script.js is the file connected to main html file of the electron app.
index.js
const {app, BrowserWindow} = require('electron');
const path = require('path');
const url = require('url');
let window;
var APP_DIR = '/app/';
var IMG_DIR = '/images/';
function createWindow() {
window = new BrowserWindow({
webPreferences: { nodeIntegration: true },
width:610,
height:679,
icon: path.join(__dirname, APP_DIR, IMG_DIR, 'icon.png'),
frame: false,
resizable: false,
fullscreenable: false
});
window.loadURL(url.format({
pathname: path.join(__dirname, APP_DIR, 'index.html'),
protocol: 'file:',
slashes: true
}));
}
app.on('ready', createWindow);
script.js (where the error occurs)
var {BrowserWindow} = require('electron').remote;
BrowserWindow.getFocusedWindow().on('blur', function() {
windowBlurHandler(); //a function
});
How can I fix it?
Function BrowserWindow.getFocusedWindow() returns null when all windows are blurred. You are getting the error because listeners cannot be registered on null.
Try something like this instead:
const mainWindow = require('electron').remote.getCurrentWindow()
mainWindow.on('blur', function() {
windowBlurHandler()
})
I am building an electron app. The app runs without any errors but does not open. I am running windows 7 on a 32 bit machine. My main.js file looks like this:
const {app, BrowserWindow} = require('electron');
const path = require('path');
const url = require('url');
// Initialize window
let win;
function createWindow() {
win = new BrowserWindow({
width: 800,
height: 600,
icon: __dirnaname+ '/assets/images/icon.jpg'
});
// Load Window
win.loadUrl(url.format({
pathname: path.join(__dirname, './index.html'),
protocol: 'file',
slashes: true
}));
// Close window
win.on('closed', () =>{
win = null;
});
//Run Create Window Function
win.on('ready', createWindow);
//Check Mac OS platform
app.on('all-window-closed', () => {
if(process.platform !== 'darwin') {
app.quit();
}
});
};
This line is wrong
win.on('ready', createWindow);
you meant
app.on('ready', createWindow);
outside of createWindow's scope. Like this:
function createWindow() {
...
};
app.on('all-window-closed', () => {
...
});
app.on('ready', createWindow);
I had the same problem after I upgraded electron from v3.x to v8.x it started working
I'm trying to download a torrent with Electron and Node.js using WebTorrent. Well, this is my code in main.js
const electron = require('electron')
const { app, BrowserWindow } = electron
const path = require('path')
const url = require('url')
const server = require('./server')
let win
function createWindow() {
win = new BrowserWindow ({ vibrancy: 'dark', width: 400, height: 600, frame: false, resizable: false, transparent: true })
win.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file',
slashes: true
}))
}
app.on('ready', createWindow)
And my code in server.js is:
require('http').createServer(function (req, res) {
var WebTorrent = require('webtorrent-hybrid')
var client = new WebTorrent()
var magnetURI = 'magnet:?xt=urn:btih:EF3B95AEF1C94FC8E98825386C3B12560FE21CFF&tr=udp://glotorrents.pw:6969/announce&tr=udp://tracker.opentrackr.org:1337/announce&tr=udp://torrent.gresille.org:80/announce&tr=udp://tracker.openbittorrent.com:80&tr=udp://tracker.coppersurfer.tk:6969&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://p4p.arenabg.ch:1337&tr=udp://tracker.internetwarriors.net:1337'
client.add(magnetURI, { path: 'movies' }, function (torrent) {
torrent.on('done', function () {
console.log('torrent download finished')
})
})
res.end('Hello from server started by Electron app!');
}).listen(9000)
The problem starts when I run the app and appears this message on the console:
(node:9032) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 ready listeners added. Use emitter.setMaxListeners() to increase limit
Its just a warning!!!
As per the Nodejs.org documentation
https://nodejs.org/api/events.html#events_emitter_setmaxlisteners_n
By default EventEmitters will print a warning if more than 10 listeners are added for a particular event. This is a useful default that helps finding memory leaks. Obviously, not all events should be limited to just 10 listeners. The emitter.setMaxListeners() method allows the limit to be modified for this specific EventEmitter instance. The value can be set to Infinity (or 0) to indicate an unlimited number of listeners.
So you need to add a below line in your code
"emitter.setMaxListeners(n)"
Building my first electron app and I'd like the workflow to be as follows:
mainWindow opens -> user clicks 'open' button -> 2nd window opens -> user enters input/hits submit -> mainWindow opens back up displaying user input
Below is my app.on('ready') from my main.js. The application startup (win.loadURL) works fine, as does the open-new-window event. The weirdness comes in the input-broadcast.
When the user enters input in the second window, the main window will re-open. However, the text in the console.log in the input-broadcast does not appear, and the input-received never fires in the main window's renderer.
Not sure what I'm doing wrong, however I may be using the wrong design pattern as well. Any help would be greatly appreciated!
main.js
const {app, BrowserWindow, ipcMain, remote} = require('electron');
const url = require('url');
const path = require('path');
const countdown = require('./countdown');
let win;
const windows = [];
app.on('ready', () =>{
console.log('app ready');
ipcMain.on('open-new-window', () =>{
console.log('trying to open window');
win.loadURL(url.format({
pathname: path.join(__dirname, 'enterValue.html'),
protocol: 'file:',
slashes: true
}));
});
ipcMain.on('input-broadcast', (evt, data) =>{
console.log('input-broadcast happened in main');
win.webContents.send('input-received', data);
win.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}));
});
win = new BrowserWindow({width: 800, height: 600});
win.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}));
win.on('closed', () =>{
console.log('closed');
win = null;
});
})
renderer.js (assoc. with the index.html)
console.log('from renderer1');
const {ipcRenderer} = require('electron');
document.getElementById('start').addEventListener('click', ()=>{
ipcRenderer.send('open-new-window');
console.log('window button clicked');
});
ipcRenderer.on('open-new-window', (evt, count) =>{
document.getElementById('userInput').innerHTML(count);
});
ipcRenderer.on('input-received', (evt, data) =>{
console.log('input received');
console.log(evt);
console.log(data);
});
renderer2.js (assoc. with the user enterValue.html)
console.log('from renderer2');
const {ipcRenderer} = require('electron');
document.getElementById('submitButton').addEventListener('click', (evt, input)=>{
var input = document.getElementById('randomInput').value;
ipcRenderer.send('input-broadcast', input);
});
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
<p>Your input was <span id="userInput"></span><p>
<button id="start">Open</button>
<script>require('./renderer')</script>
</html>
enterValue.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p>Enter a name</p>
<input type="text" id="randomInput" placeholder="enter a value"/>
<button id="submitButton">Submit</button>
<script>require('./renderer2.js')</script>
</body>
</html>
Your call order is not right when sending input back to renderer.js. You call
win.webContents.send('input-received', data)
when index.html is not yet re-loaded into win!
To fix this you should swap the calls and make sure that the content is ready when you send ipc message
ipcMain.on('input-broadcast', (evt, data) => {
console.log('input-broadcast happened in main')
win.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
win.webContents.once('dom-ready', () => {
win.webContents.send('input-received', data)
})
})