Detect Key Press in System - node.js

I am trying to detect a keypress event outside the console tab, I have allready tried input-event (for linux), hotkeys-js (for browser), and iohook (gives error). How can I do it?

I found a way. I used iohook, but the version 0.6.6 since the new version crashed, and called the start method.
iohook.on('keypress', (res) => {
let key = String.fromCharCode(res.rawcode);
console.log(key);
});
iohook.start();

Related

NodeJS blessed no key events

I am new to using the blessed library and so far, I could not get key events to work.
I would expect the following piece of code to print q whenever the Q key is pressed and Enter whenever the Enter key is pressed. It should also print keypress whenever any key is pressed.
const blessed = require('blessed');
const screen = blessed.screen({
smartCSR: true,
title: 'Title',
});
screen.key('q', () => console.log('q'));
screen.key('Enter', () => console.log('Enter'));
screen.on('keypress', () => console.log('keypress'));
screen.render();
The actual behavior is that if any "printable" key (such as alphanumeric characters) is pressed then that key is just written to the console (just as if it was typed regularly). keypress is not printed either.
The behavior is slightly different for the Enter key. Enter is still not being printed, but keypress is.
Is there anything wrong with my setup? I am using the default Gnome terminal under ArchLinux. However, that should not cause an issue because the program json-log-viewer, which is also blessed-based, works just fine.
The problem was with nodemon, fixed by passing the flag -I. See here.

How to prevent(delay) OS(Windows 10) from closing Electron window?

I have made a desktop application using electron + node.js.
Sometimes Windows does automatic updates and restarts the OS.
I want to prevent Windows 10 from restarting until the data is saved (database is online so it takes some time to store data) in software.
Right now, I am using the below code to prevent the window from closing. After data save I am calling ipcMain.on('',function()) method and make lockwindow to true then i am calling window close method.
It is working when normally window close or use shortcut keys for a close window.
But this event is not emitted in case of force close or studown/restart
mainWindow.on('close', event => {
if (lockWindow) {
mainWindow.webContents.send('save', '');
mainWindow.webContents.once('dom-ready', () => {
mainWindow.webContents.send('save', '');
});
event.preventDefault();
createdialogWindow();
} else
mainWindow = null
})
Thank You.
Have a look at window events, specifically close and beforeunload.
You will have only limited time before the system restarts itself anyway.
If the OS or the user decides to kill your app, this is what is going to happen anyway (you can also upset / anger user for not playing nicely).
Lastly, would you like your application to be the reason why some crucial security updates did not install?
HTH

Cross distribution terminal opening

In electron, I am registering a shortcut to open a terminal:
globalShortcut.register('CommandOrControl+Alt+Shift+P', () => {
spawn(os.platform() === 'linux' ? 'xterm' : 'cmd');
});
I noticed that xterm don't have the same "style" of the terminal opened from OS menu and I found that the latter is customized by the Desktop Environment (I have an Ubuntu Mate where its terminal is mate-terminal and a RedHat 7.5 with konsole).
I read here that nodejs don't have an API to detect the distribution, so it seems not feasible to know which terminal to run depending on distribution.
Is there any way to open the correct terminal or to style xterm as the OS one?
TL;DR: There's no standardised API for that and you cannot be sure that a distribution indicates the terminal application.
First of all, XTerm, Mate's Terminal, Konsole, etc. are all different applications. And because Ubuntu Mate under the hood reports as Ubuntu, AFAIK, you cannot even be certain that this is the application registered as "the" terminal app. Also, nearly every desktop environment brings its own terminal application, and since you can install multiple terminal applications side by side, it is at most an educated guess to automatically select an "appropriate" terminal application.
However, there are multiple approaches which can be considered to solve this (aesthetic) problem:
Let the user decide what terminal application they want. If your application has a configuration file, you could use that to write a value specified by the user and take that as the terminal app. In theory, they could specify a path to an application which is not a terminal app, but then it's their fault.
Compile a list of known terminal applications and check if they're installed. For example, you could make an (ordered) list of the apps your application should search for and if none of them is found, fall back to XTerm (because that is installed on most if not all desktop systems running Linux). To see if an application is installed and runnable on Linux, you can use the which command. Example:
const { spawnSync } = require ("child_process");
const terms = [ "konsole", "mate-terminal", "gnome-terminal" /* ... */ ];
var terminal = null;
// In your startup method (e.g. before opening a BrowserWindow)
if (os.platform () === "linux") {
for (term in terms) {
which = spawnSync ("which", [term]);
if (which.status !== null && which.status === 0) { // Command found
terminal = term;
break;
}
}
if (terminal === null) terminal = "xterm";
} else {
terminal = "cmd";
}
Of course you could also use spawn in favour of spawnSync but this will get more complex. Also, this only provides you with the first application found to be installed, it does not select the one "appropriate" for the desktop environment. But I believe it is a good step in the right direction if you want your application the be (somewhat) seemlessly integrated into the DE.
As a side note, your code does not take MacOS into account, but it is also possible to open a terminal on MacOS, it's simply called "Terminal" there.
Node.js doesn't provide a method to detect the name of the distribution natively, because there is no standard way to get that information from different Linux distributions.
But you can do it with a library sush as getos:
const getos = require('getos');
getos((err, os) => {
if (err) return console.log(err);
console.log(os.dist, os.codename)
})
There is a package called OpenTerm, it has configurable function which automatically determines terminal to use, and it currently supports windows and linux, but not MacOs.
const { VTexec } = require('open-term')
VTexec('help') // Runs "help" command in determined terminal.
"help" command would work both on bash and cmd. So i use it here as example.

Electron Atom File Type Association in Windows Registry

I'm building an app in Electron boilerplate and need to associate a custom file type in the Windows registry and Mac plist in order to open these files in my app.
The Mac seems fairly straight forward and have found some info from others that have managed to do this so not too concerned with Mac.
On the Windows side my first thought is to just use the winreg npm to write the keys to the registry. Seems easy enough in theory, the only problem is the docs for how to use winreg is pretty sparce at best.
I'm able to run the example code fine and spit out the autorun programs so it's installed and working fine and reading/outputting stuff makes sense to me. What I can't seem to find much info on is actually writing new keys to the registry, I'm assuming I would use create(cb) to do this but I can't seem to get it to work and honestly just the create(callback) structure doesn't really seem to make sense since there's really no logic there to pass the key, I've tried create('key to add', function() { but I'm sure that's not how you're supposed to do it hence it doesn't work lol.
Basically all I really want to do is something like this (taken from c# example):
Registry.SetValue(#"HKEY_CURRENT_USER\Software\Classes\mycompany.appname.v1\shell\open\command", null, #"c:\path\to\app.exe \"%1\"");
Registry.SetValue(#"HKEY_CURRENT_USER\Software\Classes\.myextension", null, "mycompany.appname.v1");
How to actually add new registry key values within node winreg?
We can access registry using command prompt in windows. I tried using those commands it worked fine, created a child-process and executed the command, if we type reg/? we can see all the ways we can use that command. you can see detailed about reg here [registry commands]: https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/reg . In electron we can use it like require(child-process).exec('REG ADD HKLM\Software\MYKEY'); (this adds a key to software).
The equivalent of your C# example would look something like this (using promises, since I don't like nesting callbacks):
const setKeys = new Promise((resolve, reject) => {
const regKey = new Registry({
hive: Registry.HKCU,
key: '\\Software\\Classes\\mycompany.appname.v1\\shell\\open\\command'
});
regKey.set(
Registry.DEFAULT_VALUE, Registry.REG_SZ, 'c:\\path\\to\\app.exe "%1"',
error => (error ? reject(error) : resolve())
);
})
.then(() => new Promise((resolve, reject) {
const regKey = new Registry({
hive: Registry.HKCU,
key: '\\Software\\Classes\\.myextension'
});
regKey.set(
Registry.DEFAULT_VALUE, Registry.REG_SZ, 'mycompany.appname.v1',
error => (error ? reject(error) : resolve())
);
})
.then(() => console.log('Extension registered!'))
.catch(error => console.log(error));

Hide status bar in UWP

I have used below code to hide status bar in UWP. When I run the app in development mode in my computer the status bar is not shown in windows phone. I deployed the app in Windows Store, after downloading the app, I see the status bar appears in my app.
Here is my code:
var isAvailable = Windows.Foundation.Metadata.ApiInformation.IsTypePresent(typeof(StatusBar).ToString());
if (isAvailable)
hideBar();
async void hideBar()
{
StatusBar bar = Windows.UI.ViewManagement.StatusBar.GetForCurrentView();
await bar.HideAsync();
}
The question is, why the above code shouldn't work in windows store?
Also, I have the link to my app App link in windows store, but when i search for exact key word in windows store, my application is not shown in windows store, but clicking in link would appear my app in window store.
Thanks!
Checking for the Contract, rather for the type StatusBar works fine for me.
private async Task InitializeUi()
{
// If we have a phone contract, hide the status bar
if (ApiInformation.IsApiContractPresent("Windows.Phone.PhoneContract", 1, 0))
{
var statusBar = StatusBar.GetForCurrentView();
await statusBar.HideAsync();
}
}
You have to use FullName instead of ToString():
...
ApiInformation.IsTypePresent(typeof(StatusBar).FullName);
...
This code won't work because after .Net Native compilation (which Store does) typeof(StatusBar).ToString() will not return the literal type name as you expect, but will return something like "EETypeRVA:0x00021968". Use literal string instead (you aren't going to rename StatusBar, right? ;) or use IsApiContractPresent or typeof(StatusBar).FullName (as was already advised).
P.S. The same issue can be reproduced without publishing, just run it using Release configuration.
Could it be that when you compile in Release and with the .NET Native toolchain, the type info gets discarded and so you're not passing the string you think you're passing? Maybe you can try hard-coding the full type name?
In Windows 10 the command is
Window.Current.SetTitleBar(null);

Resources