Use ShareArrayBuffer from an electron app - electron

We have an electron app which uses ShareArrayBuffer. It was written with a very old version of electron. When we updated the electron version in order to use SIMD instructions in WASM, it started showing an error saying ShareArrayBuffer is not defined. It seems it is due to the security update in Chromeum and ShareArrayBuffer is available iff Cross Origin Isolation is set.
Google shows some articiles explaining how to enable Cross Origin Isolation on web-pages, but I have not found any article that explains how to do that on an electron app. Does anyone have a pointer to the info or an idea to try?
Thank you,

It can be enabled by adding the following line in background.js
app.commandLine.appendSwitch('enable-features','SharedArrayBuffer')
Reference

As of December 2022, this is the only thing that worked for me:
browserWindow = new BrowserWindow({...});
// Enable SharedArrayBuffer
browserWindow.webContents.session.webRequest.onHeadersReceived((details, callback) => {
details.responseHeaders['Cross-Origin-Opener-Policy'] = ['same-origin'];
details.responseHeaders['Cross-Origin-Embedder-Policy'] = ['require-corp'];
callback({ responseHeaders: details.responseHeaders });
});

Related

How to check if a key is pressed in Electron?

Is it possible to check if a key is pressed in Electron? I'm not asking to detect when a key is pressed.
When my app starts, I want to be able to hold shift while it starts, before the window loads, to open a special menu. An example of what I'm looking for is:
app.whenReady().then(() => {
const win = new BrowserWindow({ show: false })
win.loadFile("whatever.html")
// ***
const openSpecialMenu = keyboard.shiftKeyHeld
// ***
// do other stuff
window.show()
})
I don't know if there's an easy way to do this, but I believe you can do this using native APIs.
On Windows you can use GetKeyState.
On macOS you can use the function described in this answer.
You can then build a native node addon that allows you to use these native APIs in your Electron JavaScript code.
In fact, I found a node module for Windows that does what you need: https://github.com/Zysen/node-asynckeystate
You need to do additional work to support other operating systems.

How do I connect xterm.js(in electron) to a real working command prompt?

I've dug myself into a deep rabbit hole trying to find out what the title says. If you're confused about what this question is, I'll give a more detailed explanation: Have you ever seen the VSCode Terminal? or Terminus? Well I want to do what those applications do. I have an electron app, and for the users convenience I want to include a command prompt of some sorts into it. I've looked in to xterm.js, but I can only find examples of things like SSH, not a direct link to a console hosted on the system. What I'm asking is how do I connect xterm.js(in electron) to a real working command prompt? I've seen programs able to interact with cmd.exe such as Windows Terminal. I'll use it as an example.
Image taken from process hacker
In the attached photo you can see three processes. WindowsTerminal.exe, OpenConsole.exe, and cmd.exe. After digging around in the source code of Windows Terminal, I can see the OpenConsole.exe gets started with every instance of a cmd that you make. So I assume that is the program that's interacting with cmd.exe. Now I know that Windows Terminal is made using UWP but you can see similar things happening with VSCode(I opened a bunch of terminals to demonstrate)
here is another post with a similar question, but with no answers. I hope this one gains some traction.
So if you can answer, thanks. If you got sidetracked a bit, remember my question: How do I connect xterm.js(in electron) to a real working command prompt?
Sorry if you couldn't understand my wording, im not very good at this :P
The following video was helpful for me. Shortly, you need to :
install node-pty and electron-rebuild packages (additional to the xterm)
Place the following codes to appropriate process files
In the main process (main.js):
const os = require('os');
const pty = require('node-pty');
var shell = os.platform() === "win32" ? "powershell.exe" : "bash";
var ptyProcess = pty.spawn(shell, [], {
name: 'xterm-color',
cols: 80,
rows: 24,
cwd: process.env.HOME,
env: process.env
});
ptyProcess.on("data", (data) => {
mainWindow.webContents.send("terminal-incData", data);
});
ipcMain.on("terminal-into", (event, data)=> {
ptyProcess.write(data);
})
In the renderer process:
const Terminal = require('xterm').Terminal;
const FitAddon = require('xterm-addon-fit').FitAddon;
const term = new Terminal();
const fitAddon = new FitAddon();
term.loadAddon(fitAddon);
// Open the terminal in #terminal-container
term.open(document.getElementById('terminal-container'));
term.onData(e => {
ipcRenderer.send("terminal-into", e);
} );
ipcRenderer.on('terminal-incData', (event, data) => {
term.write(data);
})
// Make the terminal's size and geometry fit the size of #terminal-container
fitAddon.fit();
run electron-rebuild command if you get an error.
You might get the following errors when you try to install electron-rebuild package:
Solution for MAC: error: no template named 'remove_cv_t'.
Solution for Windows: gyp ERR! find Python
I figured it out, code on github: https://github.com/77Z/electron-local-terminal-prototype

Electron: how to close a portable app on pulling out the pendrive

I made a portable app with electron. It works fine. I have it saved in a pendrive, so I don't need to install it and copy into my hard disk to run it. Just executing the app from the pendrive I have it running in my desktop. But what I need, is implement a system that makes that if you pull out the pendrive the app automatically closes. I've been googling something similar and found many ways for using a pendrive as a master key. But that isn't exactly what I need. I don't want to shutdown the PC, I only need to close the app and remove it from memory. There is any way or nodejs library that can help me with that?
You can use node_usbspy module to watch the usb insertion/removal. This module supports only Windows.
If you receive an event with device_status as 0 then you could quit the app with app.quit()
Hope it helps you!
Note: I'm the author of node-usbspy.
I found a practical solution that could work on all platforms:
const basePath = app.getAppPath()
setInterval(() => {
const path = basePath.split('/')
const baseDir = path.slice(0, -1).join('/')
fs.writeFile(baseDir + '/portable.txt', '1', err => {
if(err) {
app.quit()
}
})
}, 1000)
The script above try to save a TXT file every second. If fs.writeFile returns an error, app.quit() is called closing the application.

Options page not showing

I'm writing a new add-on as a Web Extension. In my package.manifest, I have the options_ui set:
"options_ui": {
"page": "options.html"
}
But in about:addons, the options button is not present.
So I tried to call the page directly from my background script:
runtime.openOptionsPage();
But I get this error:
Message: ReferenceError: runtime is not defined
Same error type with:
chrome.runtime.openOptionsPage();
Message: ReferenceError: chrome is not defined
I'm probably missing something very obvious there. I tested with Firefox ESR 45.0.4 and the latest Firefox Dev edition (51.0a2). How can I get the options page to show in about:addons and how can I call it from my background script?
It's browser.runtime.blah or chrome.runtime.blah.
I'm not sure if ESR 45 supports it.
This code should go in you background script right?
Please post more of your code so i can update my answer.
It turns out that I was mixing Web extensions with Add-on SDK

How can you get information about other apps running or in focus?

My motivation: I'm writing an app to help with some quantified self / time tracking type things. I'd like to use electron to record information about which app I am currently using.
Is there a way to get information about other apps in Electron? Can you at least pull information about another app that currently has focus? For instance, if the user is browsing a webpage in Chrome, it would be great to know that A) they're using chrome and B) the title of the webpage they're viewing.
During my research I found this question:
Which app has the focus when a global shortcut is triggered
It looks like the author there is using the nodObjc library to get this information on OSX. In addition to any approaches others are using to solve this problem, I'm particularly curious if electron itself has any way of exposing this information without resorting to outside libraries.
In a limited way, yes, you can get some of this information using the electron's desktopCapturer.getSources() method.
This will not get every program running on the machine. This will only get whatever chromium deems to be a video capturable source. This generally equates to anything that is an active program that has a GUI window (e.g., on the task bar on windows).
desktopCapturer.getSources({
types: ['window', 'screen']
}, (error, sources) => {
if (error) throw error
for (let i = 0; i < sources.length; ++i) {
log(sources[i]);
}
});
No, Electron doesn't provide an API to obtain information about other apps. You'll need to access the native platform APIs directly to obtain that information. For example Tockler seems to do so via shell scripts, though personally I prefer accessing native APIs directly via native Node addons/modules or node-ffi-napi.
2022 answer
Andy Baird's answer is definitely the better native Electron approach though that syntax is outdated or incomplete. Here's a complete working code snippet, assumes running from the renderer using the remote module in a recent Electron version (13+):
require('#electron/remote').desktopCapturer.getSources({
types: ['window', 'screen']
}).then(sources => {
for (const thisSource of sources) {
console.log(thisSource.name);
}
});
The other answers here are for the rendering side - it might be helpful to do this in the main process:
const { desktopCapturer } = require('electron')
desktopCapturer.getSources({ types: ['window', 'screen'] }).then(async sources => {
for (const source of sources) {
console.log("Window: ", source.id, source.name);
}
})

Resources