My electron main.js code:
function createWindow () {
const { screen } = require('electron');
const primaryDisplay = screen.getPrimaryDisplay();
const { width, height } = primaryDisplay.workAreaSize;
let mainWindow = new BrowserWindow({
width,
height,
webPreferences: {
webSecurity: false,
},
});
return mainWindow;
}
function createServerProcess () {
serverProcess = fork(__dirname + '/index.js');
}
app.whenReady().then(async () => {
createServerProcess();
let mainWindow = createWindow();
let workspaceId = await localStorage.getItem('workspaceId');
if (!workspaceId) {
workspaceId = 'abc';
}
let url = `http://${workspaceId}.localhost:8443`;
setTimeout(() => {
mainWindow.loadURL(url);
}, 3000);
});
I am using electron-forge to build my electron app, using electron-forge start to start local app works fine. But when starting the app generated by electron-forge make command, it shows below error:
I have already set webSecurity to false, for turning off cross origin restriction. Just don't know why while local app works fine but generated app is not working. I am confused. I am new to Electron.
On macOs, there's an app event open-file that's triggered when opening a file association with your app. Which allows you to open your file in an existing app window.
On windows when opening a new file it just creates a new app window instead of opening it in the existing one.
How do I get behaviour like in macOs on windows?
my code:
app.on('will-finish-launching', () => {
app.on('open-file', async (event, path) => {
event.preventDefault()
if (!win) {
win = await createWindow()
}
let openFilePath
if (process.platform === 'win32' && process.argv.length >= 2) {
openFilePath = process.argv[1]
}
if (process.platform === 'darwin') {
openFilePath = path
}
win.webContents.send('open-file', openFilePath)
})
})
app.on('ready', async () => {
if (!app.isPackaged && !process.env.IS_TEST) {
// Install Vue Devtools
try {
await installExtension(VUEJS_DEVTOOLS)
} catch (e) {
console.error('Vue Devtools failed to install:', e.toString())
}
}
if (!win) {
win = await createWindow()
}
})
The docs mention that you need to call event.preventDefault() in order to handle it. It also fires before the ready event. Have you tried something like this?
app.on("open-file", (event, path) => {
event.preventDefault();
if (mainWindow === null) {
// create the main window here
// this is usually done on app.on("ready")
// but this event fires before "ready"
}
// if you already had a mainWindow or just finished
// creating it for the first time then handle the file
let file = null;
let openFilePath = null;
if (process.platform == "win32" && process.argv.length >= 2) {
openFilePath = process.argv[1];
}
if (process.platform == "darwin") {
openFilePath = path;
}
file = fs.readFileSync(openFilePath, "utf-8");
// now do stuff with the file such as sending it to the renderer
mainWindow.webContents.send("file-opened", file);
});
ok so I have been cracking my head over this problem for the last 2 days.
The default exit button of an electron.js app doesn't work.
Whenever I run my app and I click on the exit button, it doesn't show any error in the terminal and doesn't close the app either.
So far, these are the code snippets I have used:
// functions I used
app.on('window-all-closed') {
}
app.on('close') {
}
// the code inside the functions I used
_____________________________________
app.destroy()
_____________________________________
app.exit()
_____________________________________
app = null;
And I haven't used any HTML code since I am loading the URL of the page I want to make as an app like this:
function createWindow () {
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
width: 720,
height: 600,
icon:'assets/icons/win/icon.png',
})
win.loadURL('https://insert-link')
win.removeMenu()
win.on("closed", () => mainWindow.destroy());
}
const { app } = require('electron')
app.whenReady().then(createWindow)
app.once('window-all-closed', function() {
app.quit().then(app.destroy())
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
Please help me on this.
I'm trying to develop an Electron application but I am dealing with this frustrating issue. It does not start but has no errors.
What I have tried so far:
Reinstalled Windows 10
Installed Windows Build Tools
Installed Python 2.7
Tried Electron example code
Additional Information
Node version v11.0.0
Electron version v3.0.6
Yarn version v1.12.1
What is the problem? I have tried installing via npm and yarn but that didn't work either.
Code
const {app, BrowserWindow} = require('electron')
let mainWindow
function createWindow () {
mainWindow = new BrowserWindow({width: 800, height: 600})
mainWindow.loadFile('index.html')
mainWindow.on('closed', function () {
process.stderr.write('Closed')
mainWindow = null
})
}
app.on('error', error => {
process.stderr.write(error)
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('ready', function () {
if (mainWindow === null) {
createWindow()
}
})
Output
No error output.
I do however see the process in Task Manager but no window.
mainWindow is not equal to null that's why it doesn't run createWindow() function. Change this:
app.on('ready', function () {
if (mainWindow === null) {
createWindow()
}
})
To:
app.on("ready", createWindow);
Just a wild guess. . . but I don't see where you are calling window.show()
mainWindow.on('ready-to-show', () => {
mainWindow.show()
})
That could go in the "app ready` function.
I've got an Electron app that shows a tray icon, which, when clicked, shows my main window. works great in development mode, but when I package it, (into a .app file), and double click the .app file, none of the menus show up, and more importantly, the icon doesn't show up, and so the user can never see my app.
I'm using the electron React/Redux Boilerplate (https://github.com/chentsulin/electron-react-boilerplate)
here's my main.dev.js file - any guesses are appreciated:
import { app, BrowserWindow, Tray } from 'electron';
import MenuBuilder from './menu';
let mainWindow = null;
let tray;
if (process.env.NODE_ENV === 'production') {
const sourceMapSupport = require('source-map-support');
sourceMapSupport.install();
}
if (
process.env.NODE_ENV === 'development' ||
process.env.DEBUG_PROD === 'true'
) {
require('electron-debug')();
const path = require('path');
const p = path.join(__dirname, '..', 'app', 'node_modules');
require('module').globalPaths.push(p);
}
const installExtensions = async () => {
const installer = require('electron-devtools-installer');
const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
const extensions = ['REACT_DEVELOPER_TOOLS', 'REDUX_DEVTOOLS'];
return Promise.all(
extensions.map(name => installer.default(installer[name], forceDownload))
).catch(console.error);
};
/**
* 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();
}
});
const getWindowPosition = () => {
const windowBounds = mainWindow.getBounds();
const trayBounds = tray.getBounds();
// Center window horizontally below the tray icon
const x = Math.round(
trayBounds.x + trayBounds.width / 2 - windowBounds.width / 2
);
// Position window 4 pixels vertically below the tray icon
const y = Math.round(trayBounds.y + trayBounds.height + 4);
return { x, y };
};
function createTray() {
const path = require('path');
const iconPath = path.join(__dirname, 'confluence.png');
tray = new Tray(iconPath);
tray.setToolTip('Confluence Helper');
tray.on('click', event => {
toggleWindow();
// Show devtools when command clicked
if (mainWindow.isVisible() && process.defaultApp && event.metaKey) {
mainWindow.openDevTools({ mode: 'detach' });
}
});
}
const toggleWindow = () => {
if (mainWindow.isVisible()) {
mainWindow.hide();
} else {
showWindow();
}
};
const showWindow = () => {
const position = getWindowPosition();
mainWindow.setPosition(position.x, position.y, false);
mainWindow.show();
mainWindow.focus();
};
app.on('ready', async () => {
if (
process.env.NODE_ENV === 'development' ||
process.env.DEBUG_PROD === 'true'
) {
await installExtensions();
}
mainWindow = new BrowserWindow({
show: false,
width: 500,
height: 728,
icon: `${__dirname}/confluence.icns`
});
mainWindow.loadURL(`file://${__dirname}/app.html`);
createTray();
// #TODO: Use 'ready-to-show' event
// https://github.com/electron/electron/blob/master/docs/api/browser-window.md#using-ready-to-show-event
mainWindow.webContents.on('did-finish-load', () => {
if (!mainWindow) {
throw new Error('"mainWindow" is not defined');
}
if (process.env.START_MINIMIZED) {
mainWindow.minimize();
}
});
mainWindow.on('blur', () => {
mainWindow.hide();
});
mainWindow.on('closed', () => {
mainWindow = null;
});
const menuBuilder = new MenuBuilder(mainWindow);
menuBuilder.buildMenu();
});
When i right clicked the .app file, and chose "Show Package Contents", I could see a Contents/Mac folder, and inside that was a unix executable file, which when I ran in the command line, showed me a rejected promised that had to do with my tray icon - I was doing a path.join(__dirname,'icon.png'), that ended up being the wrong path (console.log(path.join(__dirname,'icon.png')) to the rescue!
When I changed that to an absolute path ('users/myname/app/icon.png') and rebuilt, it worked!
However, this obviously won't work on OTHER people's computers - it did work on my computer(tm), but that's not good enough.
To REALLY fix it, I might have gone overboard - but this is what worked for me - by creating a NativeImage, using a path.join(__dirname,'resources','icon.png') in what I passed into that. I also added resources under build/files in package.json.
If you run into this kind of problem, i would recommend doing what I did (show package contents, etc) to see the issue in the packaged electron app.
I had the same problem on Windows (didn't tested in other OSes). Tray icon was working when running the app from VSCode, but it was invisible after packaged for Windows. Like the answer from #raingod, I was using the absolute path:
//Gets the icon to use in the tray
icon = nativeImage.createFromPath(path.join(__dirname, "build", "32x32.png"))
//Creates the tray
tray = new Tray(icon)
But what I found to be the problem was that I was pointing to a file in the "build" folder, where all the icons for my app were stored. Somehow it was causing this problem with the tray icon in the packaged app specifically. So I moved just the file used in the tray icon to another folder: "./src/icons/32x32.png". So the code looked like this:
//Gets the icon to use in the tray
icon = nativeImage.createFromPath(path.join(__dirname, "src", "icons", "32x32.png"))
//Creates the tray
tray = new Tray(icon)
Posting this here because another person might have the same problem. So use absolute path, and don't store the icon file in the "build" folder.