To achieve this task, we are going to use the child_process
class of Node.js. From child_process
we'll use spawn function, which allow us to execute a process in the background and add different event listeners. Read more about spawn function here.
Batch
In this post we'll assume that you have some knowledge with batch, however you need to know that to send information from the batch to our Electron App you'll need to output the text that you want to send using echo
.
All the text printed with echo
will be retrieven by the stdout.on("data")
event of the child_process.
echo This text will be sent as Uint8Array for being processed later by your Electron App
REM Note that you can send 2 types of data (normal and error)
REM To send normal data
echo Hello world 2>&1
REM To send error data (but don't stop the execution)
echo This text should ouput an error 1>&2
To handle the on("exit")
event of Electron and send a different exit code from batch, use the following line (change the number according to your needs):
EXIT /B 1
Electron
As said before, the data retrieven from stderr
and stdout
will have a Uint8Array format, therefore we need to convert the Uint8Array to string Javascript (if you need the array format, then don't convert it). To convert use the following line
var myReceivedData = ; // This will be the Uint8Array Data
var strData = String.fromCharCode.apply(null, myReceivedData); // The array is now human readable text
Note: the previous snippet will work for normal data. If your amount of a data is huge, you may want to change the way the data is converted, please read more about how to convert Uint8Array to string here.
Now that we know the basics , let's execute that batch !
Executing a batch file
For this example, our batch file will be the following (written for Windows electronexample.bat
):
@echo off
REM The name of the file that will be created
set filename=electronfileexample.txt
REM the path where the file will be created
set filepath=c:\
REM the content of the file
set content=Hello, this is the content of my file created with batch
REM the full path (path+filename)
set fullpath=%filepath%%filename%
echo Sending a "JSON" String
echo {"filename":"%filename%","content":"%content%","fullpath":"%fullpath%"}
REM Text to send to stdout (data)
REM Note that you can append 2>&1 to the normal stdout
REM echo This text will be sent to my Electron Project
REM or
REM echo This text will be sent to my Electron Project 2>&1
REM Text to send to stderr (error) 1>&2
REM echo This text should ouput an error 1>&2
echo An error message passing by, nothing important :) Just ignore me 1>&2
IF EXIST %filepath%%filename% (
echo File already exists
EXIT /B 1
) ELSE (
@echo Creating file in %fullpath%
(
echo %content%
) > %filepath%%filename%
)
REM Check if the file was created, if exists send code 2
REM if the file doesn't exist then send code 3 (error while creating)
IF EXIST %filepath%%filename% (
EXIT /B 2
) ELSE (
EXIT /B 3
)
A simple snippet that will check if a file exists in c:/
path, if exists send a message that says "File already exists", otherwise create the file and send the message "Creating file in c:/electronfileexample.txt
". Then check if it exists, if it exists then finish the execution with code 2
, if doesn't exists then exit with code 3
.
With Electron (using Node.js) you will need to create a child process. Unlike Python, node.js is asynchronous, that means it doesn't wait on the script.bat
to be finished. Instead, it calls functions you define previously when script.bat
prints data or exists.
Now to handle the batch from javascript, use the following code :
"use strict";
// The path to the .bat file
var myBatFilePath = "C:\\Users\\SDkCarlos\\Desktop\\electrontest.bat";
const spawn = require('child_process').spawn;
const bat = spawn('cmd.exe', ['/c', myBatFilePath]);
// Handle normal output
bat.stdout.on('data', (data) => {
// As said before, convert the Uint8Array to a readable string.
var str = String.fromCharCode.apply(null, data);
console.info(str);
});
// Handle error output
bat.stderr.on('data', (data) => {
// As said before, convert the Uint8Array to a readable string.
var str = String.fromCharCode.apply(null, data);
console.error(str);
});
// Handle on exit event
bat.on('exit', (code) => {
var preText = `Child exited with code ${code} : `;
switch(code){
case 0:
console.info(preText+"Something unknown happened executing the batch.");
break;
case 1:
console.info(preText+"The file already exists");
break;
case 2:
console.info(preText+"The file doesn't exists and now is created");
break;
case 3:
console.info(preText+"An error ocurred while creating the file");
break;
}
});
The console output should be similar to (without HTML markup, only see the console on the right side) :
You can see the previous example in the official ourcodeworld electron examples repository "electron-batch-childprocess" here. Have fun