Electron - Uncaught ReferenceError: require is not defined - electron

I have already searched in the others posts of stackflow with the same error, but aparently my problem is not about nodeIntegration parameter. Because, even the paramater of nodeIntegration is set true, i still get the undefined problem of require in the main-login.js file! PS: All files is in the same root and directory...
main.js
const { app, BrowserWindow, remote, ipcMain } = require("electron");
const path = require("path");
//Funcionalidade de criar window
function createWindow() {
const win = new BrowserWindow({
webPreferences: {
nodeIntegration: true,
preload: path.join(__dirname, "preload.js")
},
});
win.maximize();
win.loadFile("index.html");
}
//Chamada da funcionalidade de criação do window
app.whenReady().then(() => {
createWindow();
app.on("activate", function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
//Fechamento do app quando todos os windows forem fechados
app.on("window-all-closed", function () {
if (process.platform !== "darwin") app.quit();
});
//Aprovação da validação do login
ipcMain.on("validation", function (e, item) {
console.log(item);
})
index.html
<!DOCTYPE html>
<html lang="en">
<head>...</head>
<body>
<div class="container-login100" style="background-image: url('images/pdv-login.jpg');">
...
<div class="container-login100-form-btn">
<button class="login100-form-btn">
Entrar
</button>
</div>
</div>
</div>
<!--===============================================================================================-->
<script src="vendor/jquery/jquery-3.2.1.min.js"></script>
...
<script src="vendor/countdowntime/countdowntime.js"></script>
<!--===============================================================================================-->
<script src="main-login.js"></script>
</body>
</html>
main-login.js
const { ipcRenderer } = require('electron');
(function ($) {
"use strict";
...
function hideValidate(input) {
var thisAlert = $(input).parent();
$(thisAlert).removeClass("alert-validate");
$(thisAlert).find(".btn-hide-validate").remove();
}
})(jQuery);

Related

How do I display console log in electron app

I'm currently creating a JS Desktop App using Electron. I'm able to get everything functional how I want it, but I want to be able to update the users on certain tasks and also display errors in the app itself.
Is there any way to add a section (terminal if you will) or something similar inside the UI, so I can log things out to the user?
Providing application feedback to your user is as simple as having a statusUpdate function in your main process send
a message (via your preload.js script) to your render process. Within your render process, listen for a message on the
assigned channel and once received, update the content of your DOM element.
main.js (main process)
// Import required electron modules
const electronApp = require('electron').app;
const electronBrowserWindow = require('electron').BrowserWindow;
// Import required Node modules
const nodePath = require('path');
// Prevent garbage collection
let window;
function createWindow() {
const window = new electronBrowserWindow({
x: 0,
y: 0,
width: 800,
height: 600,
show: false,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: nodePath.join(__dirname, 'preload.js')
}
});
window.loadFile('index.html')
.then(() => { window.show(); });
return window;
}
electronApp.on('ready', () => {
window = createWindow();
statusTest();
});
electronApp.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
electronApp.quit();
}
});
electronApp.on('activate', () => {
if (electronBrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
// ---
function statusTest() {
let counter = 1;
let message;
setInterval(() => {
statusUpdate(`Status message ${counter} from main process.`);
counter++;
}, 1000);
}
function statusUpdate(message) {
window.webContents.send('statusMessage', message);
}
preload.js (main process)
// Import the necessary Electron modules
const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;
// Exposed protected methods in the render process
contextBridge.exposeInMainWorld(
// Allowed 'ipcRenderer' methods
'ipcRenderer', {
// From main to render
statusMessage: (message) => {
ipcRenderer.on('statusMessage', message);
}
}
);
index.html (render process)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Electron Test</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';"/>
</head>
<body>
<label for="status">Status: </label>
<textarea id="status" cols="40" rows="10" disabled></textarea>
</body>
<script>
let status = document.getElementById('status');
window.ipcRenderer.statusMessage((event, message) => {
status.value += message + '\n'; // Append message
status.scrollTop = status.scrollHeight; // Show last entry
});
</script>
</html>

Electron.js I can't do the Button action

follow my source code, does anyone know more about Electron around here? I'm starting to study now and I'm trying to create an App that will update some files through an FTP, my problem initially I put a button on the acc.html page, but I can't do its action, I've looked for several examples but with none I can do , to work, it doesn't also arrive in the script that is defined inside the acc.html.
renderer.js
// include the ipc module to communicate with main process.
const ipcRenderer = require('electron').ipcRenderer;
console.log("Chamou O Renderer.js");
document.getElementById('buttonBaixarACCCustoms').open = () => {
//ipcRenderer.send('openFile', {})
console.log("Entrou No IPCRender");
ipcRenderer.send("btnclick", arg); // ipcRender.send will pass the information to main process
}
/*
const btnclick = document.getElementById('buttonBaixarACCCustoms');
btnclick.addEventListener('onclick', function () {
console.log("Entrou No IPCRender");
var arg ="secondparam";
//send the info to main process . we can pass any arguments as second param.
ipcRenderer.send("btnclick", arg); // ipcRender.send will pass the information to main process
});
*/
app.js
const {app, BrowserWindow, ipcMain, } = require('electron');
const url = require("url");
const path = require("path");
const ftp = require("basic-ftp");
let appWindow;
function initWindow() {
appWindow = new BrowserWindow({
width: 1000,
height: 800,
webPreferences: {
contextIsolation: false,
nodeIntegration: true,
webviewTag: true
}
})
// Electron Build Path
appWindow.loadURL('file://' + __dirname + '/electron-tabs.html');
/*
appWindow.loadURL(
url.format({
pathname: path.join(__dirname, `/dist/index.html`),
protocol: "file:",
slashes: true
})
);
*/
// Initialize the DevTools.
appWindow.webContents.openDevTools();
appWindow.on('ready-to-show', function () {
appWindow.show();
appWindow.focus();
});
appWindow.on('closed', function () {
appWindow = null
})
}
app.on('ready', initWindow)
// Close when all windows are closed.
app.on('window-all-closed', function () {
// On macOS specific close process
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
if (win === null) {
initWindow();
example();
}
})
example()
async function example() {
console.log("Entrou No Example...");
const client = new ftp.Client()
client.ftp.verbose = true
try {
await client.access({
host: "127.0.0.1",
user: "topgunav",
password: "topgunav",
secure: false
})
debugger;
//console.log(await client.list());
//await client.uploadFrom("README.md", "README_FTP.md")
//await client.downloadTo("README_COPY.md", "README_FTP.md")
}
catch(err) {
console.log(err)
}
client.close()
}
//ipcMain.on will receive the “btnclick” info from renderprocess
ipcMain.on("btnclick", function (event, arg) {
console.log("Chegou Aqui No IPCMain");
//create new window
/*
var newWindow = new BrowserWindow({ width: 450, height: 300, show:
false,webPreferences: {webSecurity: false,plugins:
true,nodeIntegration: false} }); // create a new window
var facebookURL = "https://www.facebook.com"; // loading an external url. We can
load our own another html file , like how we load index.html earlier
newWindow.loadURL(facebookURL);
newWindow.show();
*/
// inform the render process that the assigned task finished. Show a message in html
// event.sender.send in ipcMain will return the reply to renderprocess
//event.sender.send("btnclick-task-finished", "yes");
});
acc.html
<!DOCTYPE html>
<html>
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
</head>
<body style="margin:0">
<h1 style="text-align: center;">Sicronização De CarSet's</h1>
<div class="mb-3">
<label for="caminhoACCCustoms" class="form-label">Informe O Caminho Da Pasta Customs</label>
<input type="text" class="form-control form-control-lg" type="text" id="caminhoACCCustoms" placeholder="C:\Users\eders\OneDrive\Documentos\Assetto Corsa Competizione\Customs">
</div>
<select class="form-select form-select-lg mb-3" aria-label=".form-select-lg example">
<option selected>Informe A Temporada Que Deseja Sicronizar</option>
<option value="1">T1</option>
<option value="2">T2</option>
<option value="3">T4</option>
<option value="3">T5</option>
</select>
<button type="button" class="btn btn-primary btn-lg" id="buttonBaixarACCCustoms">Baixar</button>
</body>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/#popperjs/core#2.10.2/dist/umd/popper.min.js" integrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa03rtR1zdB" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
<script src="../../renderer.js"></script>
</html>
electron-tabs.html
<!DOCTYPE html>
<html>
<head>
<title>SuperSync</title>
<link rel="stylesheet" href="./node_modules/electron-tabs/electron-tabs.css">
</head>
<body style="margin:0">
<div class="etabs-tabgroup">
<div class="etabs-tabs"></div>
<div class="etabs-buttons"></div>
</div>
<div class="etabs-views"></div>
</body>
<script src="./renderer.js"></script>
<script>
const TabGroup = require('electron-tabs');
let tabGroup = new TabGroup();
tabGroup.addTab({
title: "Assetto Corsa Competizione",
src: "./src/acc/acc.html",
visible: true,
active: true
});
</script>
Understanding and implementing Inter-Process Communication
can be tricky. You need a good understanding of
the Process Model
and Context Isolation.
In the below code I have greatly simplified your questions code to show only what is required to get a working IPC
process.
The purpose of this preload.js script is to define 'channel names' and the implementation of IPC between the main
process and render process(es).
This preload.js script can be included in all your window creation scripts. IE: webPreferences: { preload: 'preload.js' }.
preload.js (main process)
// Import the necessary Electron components.
const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;
// White-listed channels.
const ipc = {
'render': {
// From render to main.
'send': [
'buttonClick' // Channel name
],
// From main to render.
'receive': [],
// From render to main and back again.
'sendReceive': []
}
};
// Exposed protected methods in the render process.
contextBridge.exposeInMainWorld(
// Allowed 'ipcRenderer' methods.
'ipcRender', {
// From render to main.
send: (channel, args) => {
let validChannels = ipc.render.send;
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, args);
}
},
// From main to render.
receive: (channel, listener) => {
let validChannels = ipc.render.receive;
if (validChannels.includes(channel)) {
// Deliberately strip event as it includes `sender`.
ipcRenderer.on(channel, (event, ...args) => listener(...args));
}
},
// From render to main and back again.
invoke: (channel, args) => {
let validChannels = ipc.render.sendReceive;
if (validChannels.includes(channel)) {
return ipcRenderer.invoke(channel, args);
}
}
}
);
This preload.js script can be used in your main process and render process(es) as shown below.
/**
* Render --> Main
* ---------------
* Render: window.ipcRender.send('channel', data); // Data is optional.
* Main: electronIpcMain.on('channel', (event, data) => { methodName(data); })
*
* Main --> Render
* ---------------
* Main: windowName.webContents.send('channel', data); // Data is optional.
* Render: window.ipcRender.receive('channel', (data) => { methodName(data); });
*
* Render --> Main (Value) --> Render
* ----------------------------------
* Render: window.ipcRender.invoke('channel', data).then((result) => { methodName(result); });
* Main: electronIpcMain.handle('channel', (event, data) => { return someMethod(data); });
*
* Render --> Main (Promise) --> Render
* ------------------------------------
* Render: window.ipcRender.invoke('channel', data).then((result) => { methodName(result); });
* Main: electronIpcMain.handle('channel', async (event, data) => {
* return await promiseFunctionName(data)
* .then(() => { return result; })
* });
*/
During window creation make sure to include your preload.js script. Then listen for a message on the 'buttonClick'
channel.
main.js (main process)
const electronApp = require('electron').app;
const electronBrowserWindow = require('electron').BrowserWindow;
const electronIpcMain = require('electron').ipcMain;
const nodePath = require("path");
// Prevent garbage collection
let window;
function createWindow() {
const window = new electronBrowserWindow({
x: 0,
y: 0,
width: 800,
height: 600,
show: false,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: nodePath.join(__dirname, 'preload.js') // Include the preload.js script
}
});
window.loadFile('index.html')
.then(() => { window.show(); });
return window;
}
electronApp.on('ready', () => {
window = createWindow();
});
electronApp.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
electronApp.quit();
}
});
electronApp.on('activate', () => {
if (electronBrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
// Listen for a message on the 'buttonClick' channel
electronIpcMain.on('buttonClick', (event, data) => {
console.log(data); // Testing
})
Lastly, listen for a click event on the button, gather the data and send it via the correct IPC channel (name) to
the main process for processing.
index.html (render process)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Electron Test</title>
</head>
<body>
<h1>Sicronização De CarSet's</h1>
<label for="textField">Informe O Caminho Da Pasta Customs</label>
<input id="textField" type="text" placeholder="C:\Custom\Path"><br>
<label for="selectField">Informe A Temporada Que Deseja Sicronizar</label>
<select id="selectField">
<option value="1">T1</option>
<option value="2">T2</option>
<option value="3">T3</option>
<option value="4">T4</option>
</select><br>
<button id="button" type="button">Baixar</button>
</body>
<script>
document.getElementById('button').addEventListener('click', () => {
let data = {
textField: document.getElementById('textField').value,
selectField: document.getElementById('selectField').value
}
console.log(data); // Testing
window.ipcRender.send('buttonClick', data);
});
</script>
</html>

Button click event binding in playwright function in a new window electron js

I am new to electron and other front-end technologies. I am trying to implement a desktop app using electron. In this app on clicking a button "Run Playwright" a new window should open and run the playwright function in this new window!
I used below HTML code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Buyer-Assistant</title>
</head>
<body>
<h1>Hello World!</h1>
<button type="submit" id="btnEd" value="run playwright" >Run Playwright</button>
</body>
</html>
following the electron documentation!
main.js
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('path')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration:true,
contextIsolation: false,
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
electron preload!
preload.js
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}
for (const type of ['chrome', 'node', 'electron']) {
replaceText(`${type}-version`, process.versions[type])
}
})
by clicking on the button call this function in a new window
playwright.js
const { _electron: electron } = require('playwright');
async function runPlaywright() {
// Launch Electron app.
const electronApp = await electron.launch({
args: ['main.js']
});
// Get the first window that the app opens, wait if necessary.
const window = await electronApp.firstWindow();
// Capture a screenshot.
await window.goto('http://whatsmyuseragent.org/');
await window.screenshot({ path: 'intro.png' });
// Exit app.
await electronApp.close();
};

Electron window.webContents.send doesn't work

main.js
mainWindow = new BrowserWindow({ show: false, minWidth: 400, minHeight: 400, webPreferences: {nodeIntegration: true} });
mainWindow.maximize();
mainWindow.loadURL(url.format({
pathname: path.join(__dirname, '/html/index.html'),
protocol: 'file:',
slashes: true
}));
mainWindow.on('closed', function(){
app.quit();
});
const mainMenu = Menu.buildFromTemplate(mainMenuTemplate);
Menu.setApplicationMenu(mainMenu);
mainWindow.once('ready-to-show', () => {
mainWindow.show();
const data = {id: 'checking_for_updates', display: 'none'}
console.log(data)
mainWindow.webContents.send('change_display', data)
})
index.html
<script>
const electron = require('electron');
const ipcRenderer = electron.ipcRenderer;
ipcRenderer.on('change_display', function (event, data) {
console.log(data);
document.getElementById(data.id).style.display=data.display;
})
</script>
<body>
<!-- Checking if you can update -->
<div class="container updating" id="checking_for_updates" style="display: block">
<h1 class="updating-text">Checking for updates.</h1>
</div>
it only logs 'data' once so probably the ipcRenderer doesn't run the ipcRenderer.on change_display event. How would I fix this issue?
Your code here:
mainWindow.once('ready-to-show', () => {
mainWindow.show();
const data = {id: 'checking_for_updates', display: 'none'}
console.log(data)
mainWindow.webContents.send('change_display', data)
})
only sends the change_display once. And so you'll see data logged once as well.

Getting absolute file path from file input in isolated environment in Electron app

I am starting an Electron based desktop app, which extends existing web app capabilities.
I am interested whether I can get the absolute file path from file input. HTML is displayed inside a BrowserView, which has nodeIntegration disabled and contextIsolation enabled.
My simple test does return a valid file path in this case, though my understanding is that it shouldn’t.
Maybe I am missing something? That looks like a security vulnerability…
Can I count in my desktop app that Electron will return a valid file path in a scenario similar to the one in the code below?
main.js
const { app, BrowserWindow, BrowserView } = require('electron');
let mainWindow;
const createWindow = () => {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
});
let view = new BrowserView({
webPreferences: {
nodeIntegration: false,
contextIsolation: true
}
})
mainWindow.setBrowserView(view)
view.setBounds({ x: 0, y: 0, width: 800, height: 600 })
view.webContents.loadURL('http://localhost:8000/index.html')
mainWindow.on('closed', () => {
mainWindow = null;
});
};
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (mainWindow === null) {
createWindow();
}
});
index.html
<html>
<script type="text/javascript">
function _on_file_change_() {
file_input = document.getElementById('file1');
console.log(file_input.files[0]);
}
</script>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<input type="file" id='file1' onchange="_on_file_change_(this.files)"/>
</body>
</html>

Resources