How to detect browser close event in node js? - node.js

I have used Electron(formerly Atom Shell) to create desktop app using NodeJS.
I am using following code to open an url into browser
var spawn = require('child_process').spawn
spawn('open', ['http://www.stackoverflow.com']);
Please note that I am not using Electron BrowserWindow, this is a regular browser window.
I want to perform an action when user closes this browser window. How do I detect close event of this spawned browser?

Try utilizing the event emitter
var spawn = require('child_process').spawn,
browser = spawn('open', ['http://www.stackoverflow.com']);
browser.on('close', function() {
// Handle event
});

Related

How to detect the changes of system clipboard with nodejs

I want to detect the clipboard in my electron app.
Know someone who can answer?
It was the issue because Electron doesn't support the change event of the clipboard.
https://github.com/electron/electron/issues/2280
But thankfully, sudhakar3697 developed a node module node-clipboard-event which supports clipboard change event for Node.js/Electron.js/NW.js.
Using it, you can listen to the event in this way.
const clipboardListener = require('clipboard-event');
// To start listening
clipboardListener.startListening();
clipboardListener.on('change', () => {
console.log('Clipboard changed');
});
// To stop listening
clipboardListener.stopListening();

Is it possible to comunicate between a nodejs process and a Electron child process?

I have an Electron app that is launched inside of my main nodejs application. The user has to launch my index.js and then, an Electron window spawn. The problem is that I can't comunicate between these two processes.
I am using spawn because fork doesn't work with Electron.
Child.send doesn't work. It does nothing.
In my index.js:
let { spawn } = require("child_process")
let electron = spawn(require("electron"), ["."], {"detached": false, "cwd": "D:\\code\\electron_app", "env": {"some": JSON.stringify(["process", "env"])})
electron.send(JSON.stringify({
message: "some message"
}))
electron.on("close", (code) =>{
process.exit(code)
})
electron.on("exit", (code) => {
process.exit(code)
})
electron.stdout.pipe(process.stdout)
electron.stdio.pipe(process.stdio)
electron.stdin.pipe(process.stdin)
electron.stderr.pipe(process.stderr)
In my main.js of my Electron app:
const {app, BrowserWindow} = require('electron')
let win = null
process.on("message", console.log)
//I haven't put all functions here
This doesn't do anything. The Electron app is launching but the message is not sent. Even no errors. I don't know if there is any other way to do it.
Spawn does not support the IPC channel (which you are attempting to use) that fork does. You will need to find another approach to communicate with the process, probably something over TCP (you could use some RPC implementation or spin up a HTTP server to listen for requests in the target process)
You can use ipc with spawn. fork does this automatically.
See here: https://github.com/juliangruber/electron-stream/blob/4fefd22553b0f2bea5bca3e2d00846b96acdcb74/index.js#L87-L89
spawn(electron, args, {
stdio: [null, null, null, 'ipc']
});
ps.send('foo')
ps.on('message', (msg) => {})
The fact is although NodeJs is spawning the electron process but once new process (electron window process in this case) spawned it's become completely stranger to parent process (NodeJs in this case) until it finishes (success or error) and return something to parent process. So don't relay on IPC.
I'm assuming the fact that as NodeJs is not good for CPU intensive tasks so you want to spawn some CPU intensive task (right now on same server but later on some server less architecture).
Simply just communicate through API end points.
Develop required REST end points in NodeJs and call same in electron window process, if both are on same server, request at localhost:port from child process.
If, above not help, Please share your problem statement on UX level (what/ how you want to show).

use socket.io in chrome extension

Actually i want use socket on chrome extension.Connection should start when i open tab and it will get disconnect until chrome will get close now if i will create socket connection on content script then every time socket will get disconnect and connect again when page will get refresh so that
I have created connection on background script.
background script code:
chrome.tabs.onCreated.addListener(function callback(tabId, info){
socket = io.connect('http://localhost:3000');
});
Now i want to use same socket on content script..
for this i have made a callback on chrome.runtime.onMessage.addListener.
Callback request has came at content script but emit and on doesn't work
background script code:
chrome.runtime.onMessage.addListener( (request, sender, sendResponse)=> {
sendResponse(JSON.stringify(socket))
})

how to access the node api from a remote page in electron?

In my electron app , I load the remote page(index.html) from remote url like("http://xxxx/index.html"), then I am trying to send a ipc event to the main process then handle it , and failed, but if I put the the index.html in local fs and it is OK.
So my question is how to enable the page to access the node api (like require,ipc, etc.) from the remote page.
------ (main process)
mainWindow = new BrowserWindow({width: 800, height: 600});
// and load the index.html of the app.
mainWindow.loadUrl('http://localhost:8080');
//mainWindow.loadUrl('file://' + __dirname + '/index.html');
var ipc = require('ipc');
ipc.on('spawn-ext-process', function () {
console.log("spawn-ext-process");
});
--------- http://localhost:8080/index.html (render process)
<script>
var ipc = require('ipc');
ipc.send('spawn-ext-process');
</script>
AFIAK the ipc api doesn't use http. It essentially is sending a signal from one part of the program running on your local machine to another part of the same program on that machine.
If you want to send a signal over http you might want to use something like socket.io or websockets.
How to enable the page to access the node api (like require,ipc, etc.) from the remote page?
Depends on how you're loading the page. If you're using loadUrl on a BrowserWindow instance, node integration is enabled by default (you can disable it via the nodeIntegration option, see the docs).
If you're using a <webview> tag, then it's disabled by default and you can enable it via the nodeintegration attribute. See the docs. Note that with webview you can preload scripts that do have access to node and electron APIs safely, and then access to those objects are destroyed when the script has finished executing (see here).
Like #FelipeBrahm said, I would not give a remote page access to node.js or electron APIs unless it's your own page, and even if you do that, be cautious.

Execute createShortcut in a Squirrel event, in an Electron app

I'm trying to create shortcuts for my Electron app when I install it or update it, however I am having some trouble executing the command that is meant to create the shortcut.
By default Electron apps are "SquirrelAware", therefore I have to specify where i would like to create shortcuts.
My question is in relation to the accepted answer to this question.
Handle Squirrel's event on an Electron app
I have tried to use the exec module and the child_process module, however both did not seem to work. I am now currently attempting (and failing) to launch PowerShell and run a script in there that will create shortcuts on my Start Menu and Desktop, however I feel this is rather long and that there must be an easier way.
Here is my current attempt using the child_process module and PowerShell:
var spawn = require('child_process').spawn, child;
child = spawn("C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",["C:\\ElectronSquirrelDemo\\AddAppShortcuts.ps1 -SourceExe "+ executionPath] );
child.stdout.on('data', function(data){
console.log("PowerShell Data: " + data);
});
child.stdout.on('data', function(data){
console.log("PowerShell Error: " + data);
});
child.stdout.on('exit', function(){
console.log('PowerShell script finished');
});
Any help on this would be much appreciated
It took me awhile to understand how to do this myself. The Squirrel.Windows Update.exe has the ability to create shortcuts to your app for you. I wrote a blog post called Creating a Windows Distribution of an Electron App using Squirrel and in it I have Squirrel create the shortcuts for me. If you want to go this route, this is simplified version of how to have Squirrel create the shortcuts for you:
var cp = require('child_process');
var updateDotExe = path.resolve(path.dirname(process.execPath), '..', 'update.exe');
var target = path.basename(process.execPath);
var child = cp.spawn(updateDotExe, ["--createShortcut", target], { detached: true });
child.on('close', function(code) {
app.quit();
});
You need to hack the electron executable using Resource Hacker, rcedit, or another application to change the ProductName and Icon resources. You'll want to call the above code on both the install and updated Squirrel events.

Resources