I'm a newbie with Electron and JS.
I've searched for a solution to create a simple button which executes a .bat file or .exe file.
I've read this article about using child_process.
However, It doesn't say how to "link" var to my button.
My code is written in renderer.js
electron runs using nodejs therefore you could do something along the lines of:
var execFile = require('child_process').execFile;
var runExe = function(){
execFile('<your-name>.exe', function(err, data) {
console.log(err)
console.log(data.toString());
});
}
now call
runExe()
using your button and you should be good to go
for more info see here
node js reference
so what happens is basically that we run a specified exe file using like you already said the nodejs child_process ... hope that helped
Ok, Now is work i post my solution for electron:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
<!-- All of the Node.js APIs are available in this renderer process. -->
We are using Node.js <script>document.write(process.versions.node)</script>,
Chromium <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
<h1> A simple Javascript created button </h1>
<button onclick="function()">Firefox 1</button>
<button onclick="firefox()">Firefox 2</button>
<script>
var execFile = require('child_process').execFile;
function firefox(){
execFile("C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe", function(err, data) {
console.log(err)
console.log(data.toString());
});
}
// You can also require other files to run in this process
require('./renderer.js')
</script>
</body>
</html>
Related
I'm new in Javascript world, currently I'm trying to implement a GUI using electron js framework.
Trying to reproduce the code from a tutorial, I got stuck on a code which seems not to work on my PC, basically even if I click on a button, the console is not logging anything (when it should have!!); the aim of the code is to refer to a button defined in an index.html file from a index.js containing the script and log a sentence when the button is clicked, but it seems like the script in the html file cannot access the .js file at all. Here I'm reporting the code from index.html:
<!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>my-app</title>
<link rel = "stylesheet" href="styles.css">
</head>
<body>
<button id = "button1" > START </button>
<script>
require('./index.js');
</script>
</body>
</html>
Here the code belonging to index.js file:
const electron = require("electron");
const button1 = document.getElementById("button1");
button1.addEventListener("click", startApp);
function startApp(){
console.log("Button clicked!");
};
Note:
I've tried to debug this code based on my very little knowledge of Javascript and electron:
I used document.getElementById("button1"); in index.html and it does work (the variable obtained was used to change button text color), but the same is not working when reported in the index.js file;
I tried console.log("In index.js"); in index.js but still it is not working!
From these results I thought the problem may be the .html and .js file communication; they are in the same folder. One more thing: I downloaded the tutorial code from GitHub and the problem is still present with the same actions at points 1 and 2.
Edit: I've omitted that I'm linking index.html window and displaying it in the main.js file, in fact the windows does show up, but the the click on the button doesn't produce any action.
Seemed to be a problem with the require module not working in .html file.
Solved by replacing it with <script src="index.js"></script>.
It appears that you shoud be using electron to load the index.html via BrowserWindowonce it is ready. app and BrowserWindow are from the electron module.
`const { app, BrowserWindow } = require('electron')`
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
})
From the quick start
In Electron, browser windows can only be created after the app module's ready event is fired. You can wait for this event by using the app.whenReady() API. Call createWindow() after whenReady() resolves its Promise.
For futher info see https://www.electronjs.org/docs/tutorial/quick-start
Hope this proves useful.
Here is the folder structure for my node.js project:
MySampleApp\
MySampleApp\Package.json
MySampleApp\Server.js
MySampleApp\public:
index.html - Invoked when server.js starts and shows "Click Me" button
fetchprocess.js - check button click and then show in DocumentElementID
user1.ps1 - runs Get-Process command to fetch processes
fetchprocess.js:
console.log('Client-side code running');
const button = document.getElementById('myButton');
button.addEventListener('click', function(e) {
console.log('button was clicked');
document.getElementById('counter').innerHTML = "ClickedNow";
var ps = new shell({
executionPolicy: 'bypass',
noProfile: true
});
app.get("/", function (req, res) {
ps.addCommand("./user.ps1", [ {
name: 'guid', value: req.params.guid
} ])
ps.invoke().then(output => {
res.end(output); // This is to show the output in web browser
})
})
});
Index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Example</title>
</head>
<body>
<p id="counter">Loading button click data.</p>
<button id="myButton">Click me!</button>
</body>
<script src="fetchprocess.js"></script>
</html>
My objective is to execute "user1.ps1" when someone clicks on the "ClickMe" button and then show the data in HTML Div (Counter). When I try to run above code it throws an error that require is not defined in fetchprocess.js file.
Image:
I will have several scripts under the public folder that will be executed when someone clicks on other buttons on the web app. What is the best folder structure for such project.
Thank you very much
TL; DR; There is no way you can execute Node.js code in a browser.
Looks like you messaged up with libraries. You are trying to execute some Node.js code in the browser.
<script src="fetchprocess.js"></script>
Here you are loading the script in the browser. The truth is that Browser JS code does not have access to the platform things like PowerShell and it is not Node.js at all. If you need to execute Node.js code use Node.js executable.
UPD:
The workaround may be the following.
Spin up HTTP server locally with Node.js
Add an endpoint that runs the PS script once it receives a request.
On-click send AJAX request to your server.
But it worth noticing that it will work only on the machine where the Node.js server is running. Because it is not possible to run PowerShell from a browser.
Cannot get HTML file to call JavaScript function hello() on Ubuntu Apache 2. I have seen similar problems where the solution was to uncomment the #JSDIR line on the httpd.conf file but there is now only apache.conf and no similar line. I want to call the python script accesstest.py to write the current date and time to a text file from the main.js function after clicking the button on the HTML file. All of the files work correctly when run separately. How do I fix this?
index.html HTML code:
<!DOCTYPE html>
<html lang="en">
<head>
<title><demo</title>
</head>
<body>
<h1></h1>
<script src="main.js"></script>
<button onclick="hello();">js function</button>
</body>
</html>
main.js JavaScript code:
let myHeading = document.querySelector('h1');
myHeading.textContent = 'Hello world!';
function hello(){
var spawn = require("child_process").spawn;
var process = spawn('python,["accesstest.py"]);
alert('hello');
}
accesstest.py Python code:
import datetime
def execute():
file = open('/path/to/file/pytest.txt', 'a+')
file.write('test time: %s \n' % (datetime.datetime.now()))
file.close()
execute()
Here is the display:
page displays "Hello World!" with "js function button" that does nothing
Here are a couple solutions I found that didn't work for me:
Unable to call JavaScript function in html on button click
How to link external javascript file onclick of button
Thanks.
I just started learning Node.js and can't figure out how to load data from a local CSV file and use wink Naive Bayes Text Classifier to learn the data.
I can load the data from local CSV file using this or this example. But the problem is that I do not know how to load wink's Naive Bayes library to client side JS. Is there a way to include node's modules (like wink) in the script that I wrote below?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test Naive Bayes</title>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script src="./papaparse.min.js"></script>
</head>
<body>
<input type="file" id="csv-file" name="files"/>
</body>
<script>
// REF: https://www.joyofdata.de/blog/parsing-local-csv-file-with-javascript-papa-parse/
// http://archive.is/ySSC8
var data;
function handleFileSelect(evt) {
var file = evt.target.files[0];
Papa.parse(file, {
header: true,
dynamicTyping: true,
complete: function(results) {
data = results;
}
});
}
$(document).ready(function(){
$("#csv-file").change(handleFileSelect);
});
</script>
</html>
An easy way to use node modules when working in the browser is to use browserify. In your working directory:
npm install wink-naive-bayes-text-classifier --save
npm install -g browserify
You'll have to move your code into a separate script file, let us say process-data.js. And, from your HTML you'll be including a different script — bundle.js (we'll come to this at the end):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test Naive Bayes</title>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script src="./papaparse.min.js"></script>
</head>
<body>
<input type="file" id="csv-file" name="files"/>
<script src="bundle.js"></script>
</body>
</html>
In your process-data.js, you can now simply require the library as is shown in its documentation.
// REF: https://www.joyofdata.de/blog/parsing-local-csv-file-with-javascript-papa-parse/
// http://archive.is/ySSC8
// Load Naive Bayes Text Classifier
var Classifier = require( 'wink-naive-bayes-text-classifier' );
// Instantiate
var nbc = Classifier();
var data;
function handleFileSelect(evt) {
var file = evt.target.files[0];
Papa.parse(file, {
header: true,
dynamicTyping: true,
complete: function(results) {
data = results;
// You can now use nbc and data :)
// nbc.learn(data[0]);
}
});
}
$(document).ready(function(){
$("#csv-file").change(handleFileSelect);
});
Finally, to create the bundle.js file you'll run browserify:
browserify process-data.js -o bundle.js
This will bundle all the modules you need together into a the file that your HTML is calling. If you don't want to type so much every time you might consider adding an npm script.
I'm trying to make simple page with JS module that will do something with the page. I need to use node.js's modules so I'm learning how to browserify works.
My HTML:
<!doctype html>
<html>
<head>
<script src="js/bundle.js" type="text/javascript"></script>
</head>
<body>
<p>Hello world!</p>
<script type="text/javascript">
var test = require("./test.js");
test.init();
</script>
</body>
</html>
This is my JavaScript (test.js):
"use strict";
alert("here1");
var init = function() {
alert("here2");
}
exports.init = init
I'm making a bundle with:
browserify.cmd test.js -o bundle.js
When I'm trying to open the page it shows "here1" but doesn't show "here2".
In browser's console I see:
Uncaught ReferenceError: require is not defined index.html:9
Any ideas how to make module's function (init) work well?
You need to put all JavaScript code which contains anything from Node in the test.js file which you are then converting with the browserify into te bundle.js. In your example you are using a Node function require in the index.html which is not going to be converted. Browser then sees function require() which he doesn't know and this is where the problem is hidden.
Simply told: all your javascript code (containing Node) must be included in your index.html as a single bundle.js which is a browserifed result from your source files.
EDIT
Browserify doesn't (by default) allow you to call any browserified function out of the browserified code. But you can make it available by attaching the function into window scope.
This is test.js (which is then converted to bundle.js by browserify) and index.html
"use strict";
alert("here1");
window.init = function() {
alert("here2");
}
<!doctype html>
<html>
<head>
<script src="js/bundle.js" type="text/javascript"></script>
</head>
<body>
<p>Hello world!</p>
<script type="text/javascript">
init();
</script>
</body>
</html>