My app does not display a window when it's built, but works fine when I run npm run serve
There is still an process running in task manager, and the same thing happens if I use the installer. I don't get any errors warnings from electron-builder.
background.js:
import { app, protocol, dialog, BrowserWindow, ipcMain, shell } from 'electron'
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
import path from 'path'
import fs from 'fs'
import childProcess from 'child_process'
import ncp from 'ncp'
const isDevelopment = process.env.NODE_ENV !== 'production'
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win
// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([
{ scheme: 'app', privileges: { secure: true, standard: true } }
])
function createWindow () {
// Create the browser window.
win = new BrowserWindow({
width: 1200,
height: 600,
resizable: false,
maximizable: false,
frame: false,
webPreferences: {
// Use pluginOptions.nodeIntegration, leave this alone
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
preload: path.join(__dirname, 'preload.js')
}
})
if (process.env.WEBPACK_DEV_SERVER_URL) {
// Load the url of the dev server if in development mode
win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
if (!process.env.IS_TEST) win.webContents.openDevTools()
} else {
createProtocol('app')
// Load the index.html when not in development
win.loadURL(path.join(__dirname,'index.html'))
}
win.on('closed', () => {
win = null
})
}
// Quit when all windows are closed.
app.on('window-all-closed', () => {
// On macOS 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', () => {
// 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 (win === null) {
createWindow()
}
})
I tried the fixes here and here to no avail.
I'm using electron-vue. You can find the full code here if you need more context
The issue ended up being code present inside of the app.on('ready') function. Any additional code needs to be written after the window is created, or the issue occurs.
Related
I'm making a desktop app using Vue CLI and vue-cli-plugin-electron-builder.
I need to use multiple renderer processes to do calculations, and I tried to initiate multiple BrowserWindows in the background.js file.
The background.js file is like this:
async function createWindow() {
// Create the main browser window.
win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
// Use pluginOptions.nodeIntegration, leave this alone
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
preload: path.join(__dirname, 'preload.js')
}
})
if (process.env.WEBPACK_DEV_SERVER_URL) {
// Load the url of the dev server if in development mode
await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
if (!process.env.IS_TEST) win.webContents.openDevTools()
} else {
createProtocol('app')
// Load the index.html when not in development
win.loadURL('app://./index.html')
}
// The worker process is a renderer BrowserWindow.
const worker_process = new BrowserWindow({
show: true,
width: 1440,
height: 900,
webPreferences: {
nodeIntegration: true,
webSecurity: false,
}
})
worker_process.loadFile(path.join(__dirname, 'work.html')) // THIS line doesn't work.
...
app.on('ready', async () => {
createWindow()
})
When I ran npm run electron:serve, the "main browser window" and the "worker process" both opened up, but the "worker process" didn't load the html file. The terminal showed:
Failed to load URL: file:///D:/dev2/dist_electron/work.html with error: ERR_FILE_NOT_FOUND''
I've already had ./src/worker.html file. I seemed that vue CLI or electron didn't copy this html file into the 'distribution folder'.
I tried to change
worker_process.loadFile(path.join(__dirname, 'work.html'))
to
worker_process.loadURL('app://./work.html')
and this popped up
OS warning.
I also tried adding the following into vue.config.js. This adding only gave me more errors in compiling.
module.exports = defineConfig({
pages:{
worker: './src/preload.js',
workers1: './src/preload2.js',
},
...
})
Any suggestion is appreciated! I can also provide more information.
I am new to coding. And trying to make an electron app with react. In the app I want to save user login information in the app so that I can automatically fetch the data when the app launches. So, I am using electron-settings to save the data.
code sample:
app.jsx
...
import setting from "electron-settings";
function App() {
...
useEffect(() => {
const getUser = async () => {
return await setting.get('xpass-user')
}
console.log(getUser());
}, [])
return ...;
}
export default App;
electron.js
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('path')
const url = require('url')
const isDev = require('electron-is-dev')
function createWindow() {
// Create the browser window.
const win = new BrowserWindow({
width: 1250,
height: 900,
titleBarStyle: "hiddenInset",
autoHideMenuBar: true,
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true,
}
})
win.loadURL(
isDev
? 'http://localhost:3000'
: url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
})
)
win.webContents.openDevTools();
}
app.on('ready',createWindow)
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
the error:
ERROR in ./node_modules/electron-settings/dist/settings.js 166:27-40
Module not found: Error: Can't resolve 'fs' in
'C:\Users\learner\app\node_modules\electron-settings\dist'
ERROR in ./node_modules/electron-settings/dist/settings.js 170:29-44
Module not found: Error: Can't resolve 'path' in
'C:\Users\learner\app\node_modules\electron-settings\dist'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js
core modules by default. This is no longer the case. Verify if you
need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
add a fallback 'resolve.fallback: { "path": require.resolve("path-browserify") }'
install 'path-browserify' If you don't want to include a polyfill, you can use an empty module like this: resolve.fallback: { "path":
false }
ERROR in
./node_modules/electron-settings/node_modules/mkdirp/lib/find-made.js
3:4-19
Module not found: Error: Can't resolve 'path' in
'C:\Users\app\node_modules\electron-settings\node_modules\mkdirp\lib'
If anyone can help me I'd be grateful. Thank You
Module not found: Error: Can't resolve 'fs' in...
In create-react-app, they have stubbed out 'fs'.You cannot import it. They did this because fs is a node core module.
Add the following to the root of the "package.json" file.
"browser": {
"fs": false,
"path": false,
"os": false
}
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. This is no longer the case. Verify if you need this module and configure a polyfill for it.
to resolve this issue check this question How to Polyfill node core modules in webpack 5
I followed the suggestions in the answers of related questions, i.e. specifying
webPreferences: {
plugins: true
}
as part of the options when creating the BrowserWindow instance, but it is simply not working. Whenever I try to load/open/view a PDF file in electron, all I get is what looks like an empty/broken chromium PDF viewer like on this screenshot:
My electron version is "^13.1.2" according to my package.json and this is my main.js
// main.js
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')
const path = require('path')
function createWindow () {
// Create the browser window.
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
plugins: true
}
});
// and load the index.html of the app.
win.loadFile('test.pdf');
}
app.whenReady().then(() => {
createWindow()
})
app.on('window-all-closed', function () {
app.quit()
})
Can anyone tell me what I'm doing wrong?
An upgrade of electron helped me. i switched from 13.x to 16.x and it works now
Use PDFWindow package
`//main.js
app.on('ready', () => {
const win = new PDFWindow({
width: 800,
height: 600
})
win.loadURL('test.pdf')
})
//package.json
"dependencies": {
"electron-pdf-window": "^1.0.12",
},
`
My question is because I have been seeing how to do it for a long time and the first few times it worked, but lately I have had many problems.
I have seen several Blogs on how to link Electron with Angular but it always happens to me that I have errors with the main.js in the loadURL
const { app, BrowserWindow } = require('electron');
const url = require("url");
const path = require("path");
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
title: 'frontend',
backgroundColor: '#ffffff',
webPreferences: {
nodeIntegration: true
}
});
mainWindow.maximize();
mainWindow.webContents.openDevTools();
mainWindow.loadURL(
url.format({
pathname: path.join(__dirname, `/dist/index.html`),
protocol: "file:",
slashes: true
})
);
mainWindow.on('closed', function () {
mainWindow = null
});
}
app.on('ready', createWindow);
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit();
})
app.on('activate', function () {
if (mainWindow === null) createWindow();
})
I have already made the changes that videos and pages usually say about this as
Editing the package.json with "main": "main.js",
Put the dot in <base href ="./">
In angular.json projects> appName> architect> build> options> outputPath change it to "outputPath":"dist", without the project title
All of the above works until the time of packaging.
For what several mention using "electron-packager":"^14.2.1",
From a simpler command like
"packager": "electron-packager. --platform = win32 --out dist / --overwrite"
Where first of all, it generates an error with pathname: path.join (__ dirname, 'dist / index.html'), because it locates it somewhere else and I have to change dist / for src /
What the exe generates but at the moment of starting only the <app-root> </app-root> tag appears without the angular scripts, that is, an empty page
And others post to create the package.json script like:
"electron-package": "ng build --prod && electron-packager. --no-prune --ignore=/node_modules --ignore=/e2e --ignore=/src --overwrite"
or
"electron-package": "ng build --prod --base-href ./ && electron-packager. --no-prune --ignore=/e2e --ignore=/src --overwrite"
That the latter I think does not generate the index.html: c
Does anyone know a Definitive process with Anglar-cli and Electron?
I am trying to make a simple Electron application called my-app containing a standard main.js which creates a new browser window that points to index.html.
Inside index.html is an iframe that loads another local file called iframe.html.
Inside iframe.html is some text that when clicked calls a Javascript function launchPowershell().
This function is located inside renderer.js and will create a new Powershell object, add a command, and invoke the object.
However, whenever I run my-app, and click on the text inside iframe.html, I get an error thrown saying that "require is not defined".
Error thrown
If I move the code from iframe.html into index.html and drop the iframe, everything works fine.
So I believe I am missing something to get Electron to work correctly using an iframe. Perhaps something related to the scope of my Javascript variables.
Can anybody provide any suggestions?
package.json:
{
"name": "my-app",
"version": "0.1.0",
"main": "main.js"
}
index.html:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="renderer.js" ></script>
</head>
<body>
<iframe id="iframe" src="iframe.html"></iframe>
</body>
</html>
iframe.html:
<html>
<head>
<script type="text/javascript" src="renderer.js" ></script>
</head>
<body>
<a onclick="launchPowershell();">Launch powershell</a>
</body>
</html>
renderer.js:
function launchPowershell() {
const powershell = require('node-powershell');
// Create the PS Instance
let ps = new powershell({
executionPolicy: 'Bypass',
noProfile: true
})
// Load the gun
ps.addCommand("Powershell success!")
// Pull the Trigger
ps.invoke()
.then(output => {
console.log(output)
})
.catch(err => {
console.error(err)
ps.dispose()
})
}
main.js:
const electron = require('electron')
// Module to control application life.
// const app = electron.app
const {app, Menu, dialog} = electron
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow
const path = require('path')
const url = require('url')
// Declare some global variables
global.sharedObj = {
cred: null
};
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createMenu() {
const template = [
{
label: 'View',
submenu: [
{
role: 'reload'
},
{
role: 'forcereload'
},
{
role: 'toggledevtools'
}
]
},
{
label: 'Tools',
submenu: [
{
label: 'Check Cred',
click () {
let user = (global.sharedObj.cred) ? global.sharedObj.cred.user : "Default"
dialog.showMessageBox({
type: "info",
title: "Current Cred",
message: `The current user is: ${user}.`
})
}
}
]
}
]
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
}
function createWindow () {
// Use custom menu
createMenu()
// Create the browser window.
mainWindow = new BrowserWindow({width: 800, height: 600})
// and load the index.html of the app.
mainWindow.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
// Open the DevTools.
mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some 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()
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
Figured out my issue. Basically iFrames don't work well with Electron. It's better to use a webview. However, a webview won't work for my purpose because of security restrictions when loading external websites, even a local file.
My solution has been to simply move all my local HTML files into div's inside my main index.html file and then simply toggle their viability as needed.