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

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

Related

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.

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);
}
})

Download repository from Github

I'm trying to learn Yeoman, but find the official documentation severely lacking. I've found the remote() function which appears to download a GIT repository but whatever I do I can't get it to work without throwing errors.
Here's what I have:
this.remote('powerbuoy', 'SleekWP', 'master', function (err, remote) {
if (err) {
this.log(err);
return err;
}
remote.copy('.', this.destinationPath('wp-content/themes/sleek/'));
}.bind(this));
What I'm hoping would happen here is that the https://github.com/powerbuoy/SleekWP/ repo is downloaded and moved to wp-content/themes/sleek/. What happens instead is I get:
fs.js:603
var r = binding.read(fd, buffer, offset, length, position);
^
Error: EISDIR: illegal operation on a directory, read
Is there a better documentation or a tutorial explaining all these basics somewhere? I'd love to know how to copy files without each copy being printed to the console too for example. This all seems pretty basic but http://yeoman.io/authoring/ is very sparse.
Ok, so apparently the solution was to use remote.bulkDirectory() instead of remote.copy().
Edit: However, reading the "documentation" (can barely be called that) it says that "You should never use this method, unless there's no other solution." (http://yeoman.io/generator/actions_actions.html)
So if anyone knows of the proper way to do this I'd love to know.
I switched to the fs-extra package and used cacheRoot() and destinationRoot() to copy the directory instead:
fs.copy(this.cacheRoot() + '/username/Project/branch/', this.destinationPath('destination/path/')

LaTeX Failed to Parse(Unknown Error) on MediaWiki

On my wiki implemented by the MediaWiki interface, I am receiving a Failed to Parse (Unknown Error) for the LaTeX in the page. I checked the LocalSettings.php file, and I have set the proper variable($wgUseTeX) to true.
If it helps, the error message before this was a Failed to Parse(Missing texvc executable), but I "fixed" it to the best of my knowledge by running "make" inside the math directory and installing the texvc executable there. I tested texvc and it works on the commandline.
Could there be anything that I am missing?
aptitude install ocaml
cd /math
make clean
make
Found the answer here: MediaWiki Forums LaTeX Error
It seems that I had to clear the math directory except for the original files, rebuild ocaml, and finally rebuild texvc.
Adding this to LocalSettings solved it for me. Just needed to make the directory calls accurate. Tedious.
$wgUseTeX = true;
$wgUploadDirectory = "{$IP}/images";
$wgUploadPath = "{$wgScriptPath}/images";
$wgMathPath = "{$wgUploadPath}/math";
$wgMathDirectory = "{$wgUploadDirectory}/math";
$wgTmpDirectory = "{$wgUploadDirectory}/tmp";
$wgTexvc = "{$IP}/math/texvc";
Have a look at the README file, paying particular attention to "Ensure that the temporary and math directories exist and can be written to by the user account the web server runs under; if you don't control the server, you may have to make them world-writable."
If that does not help, edit render.ml, comment out the block that says "Commenting this block out will aid in debugging", and re-run make. This will leave all temporary files (including the TeX log) so that you can hopefully see what went wrong.

How to monitor a text file in realtime [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
For debugging purposes in a somewhat closed system, I have to output text to a file.
Does anyone know of a tool that runs on windows (console based or not) that detects changes to a file and outputs them in real-time?
I like tools that will perform more than one task, Notepad++ is a great notepad replacement and has a Document Monitor plugin (installs with standard msi) that works great. It also is portable so you can have it on a thumb drive for use anywhere.
For a command line option, PowerShell (which is really a new command line) has a great feature already mentioned.
Get-Content someFile.txt -wait
But you can also filter at the command line using a regular expression
Get-Content web.log -wait | where { $_ -match "ERROR" }
Tail for Win32
Apache Chainsaw - used this with log4net logs, may require file to be in a certain format
When using Windows PowerShell you can do the following:
Get-Content someFile.txt -wait
I use "tail -f" under cygwin.
I use BareTail for doing this on Windows. It's free and has some nice features, such as tabs for tailing multiple files and configurable highlighting.
Tail is the best answer so far.
If you don't use Windows, you probably already have tail.
If you do use Windows, you can get a whole slew of Unix command line tools from here. Unzip them and put them somewhere in your PATH.
Then just do this at the command prompt from the same folder your log file is in:
tail -n 50 -f whatever.log
This will show you the last 50 lines of the file and will update as the file updates.
You can combine grep with tail with great results - something like this:
tail -n 50 -f whatever.log | grep Error
gives you just lines with "Error" in it.
Good luck!
FileSystemWatcher works a treat, although you do have to be a little careful about duplicate events firing - 1st link from Google - but bearing that in mind can produce great results.
Late answer, though might be helpful for someone -- LOGEXPERT seems to be interesting tail utility for windows.
Try SMSTrace from Microsoft (now called CMTrace, and directly available in the Start Menu on some versions of Windows)
Its a brilliant GUI tool that monitors updates to any text file in real time, even if its locked for writing by another file.
Don't be fooled by the description, its capable of monitoring any file, including .txt, .log or .csv.
Its ability to monitor locked files is extremely useful, and is one of the reasons why this utility shines.
One of the nicest features is line coloring. If it sees the word "ERROR", the line becomes red. If it sees the word "WARN", the line becomes yellow. This makes the logs a lot easier to follow.
I have used FileSystemWatcher for monitoring of text files for a component I recently built. There may be better options (I never found anything in my limited research) but that seemed to do the trick nicely :)
Crap, my bad, you're actually after a tool to do it all for you..
Well if you get unlucky and want to roll your own ;)
Yor can use the FileSystemWatcher in System.Diagnostics.
From MSDN:
public class Watcher
{
public static void Main()
{
Run();
}
[PermissionSet(SecurityAction.Demand, Name="FullTrust")]
public static void Run()
{
string[] args = System.Environment.GetCommandLineArgs();
// If a directory is not specified, exit program.
if(args.Length != 2)
{
// Display the proper way to call the program.
Console.WriteLine("Usage: Watcher.exe (directory)");
return;
}
// Create a new FileSystemWatcher and set its properties.
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = args[1];
/* Watch for changes in LastAccess and LastWrite times, and
the renaming of files or directories. */
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
// Only watch text files.
watcher.Filter = "*.txt";
// Add event handlers.
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
// Begin watching.
watcher.EnableRaisingEvents = true;
// Wait for the user to quit the program.
Console.WriteLine("Press \'q\' to quit the sample.");
while(Console.Read()!='q');
}
// Define the event handlers.
private static void OnChanged(object source, FileSystemEventArgs e)
{
// Specify what is done when a file is changed, created, or deleted.
Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType);
}
private static void OnRenamed(object source, RenamedEventArgs e)
{
// Specify what is done when a file is renamed.
Console.WriteLine("File: {0} renamed to {1}", e.OldFullPath, e.FullPath);
}
}
You can also follow this link Watching Folder Activity in VB.NET
Snake Tail. It is a good option.
http://snakenest.com/snaketail/
Just a shameless plug to tail onto the answer, but I have a free web based app called Hacksaw used for viewing log4net files. I've put in an auto refresh options so you can give yourself near real time updates without having to refresh the browser all the time.
Yeah I've used both Tail for Win32 and tail on Cygwin. I've found both to be excellent, although I prefer Cygwin slightly as I'm able to tail files over the internet efficiently without crashes (Tail for Win32 has crashed on me in some instances).
So basically, I would use tail on Cygwin and redirect the output to a file on my local machine. I would then have this file open in Vim and reload (:e) it when required.
+1 for BareTail. I actually use BareTailPro, which provides real-time filtering on the tail with basic search strings or search strings using regex.
To make the list complete here's a link to the GNU WIN32 ports of many useful tools (amongst them is tail).
GNUWin32 CoreUtils
Surprised no one has mentioned Trace32 (or Trace64). These are great (free) Microsoft utilities that give a nice GUI and highlight any errors, etc. It also has filtering and sounds like exactly what you need.
Here's a utility I wrote to do just that:
It uses a FileSystemWatcher to look for changes in log files within local folders or network shares (don't have to be mounted, just provide the UNC path) and appends the new content to the console.
on github: https://github.com/danbyrne84/multitail
http://www.danielbyrne.net/projects/multitail
Hope this helps
#echo off
set LoggingFile=C:\foo.txt
set lineNr=0
:while1
for /f "usebackq delims=" %%i in (`more +%lineNr% %LoggingFile%`) DO (
echo %%i
set /a lineNr+=1
REM Have an appropriate stop condition here by checking i
)
goto :while1
A command prompt way of doing it.
FileMon is a free stand alone tool that can detect all kinds of file access. You can filter out any unwanted. It does not show you the data that has actually changed though.
I second "tail -f" in cygwin. I assume that Tail for Win32 will accomplish the same thing.
Tail for Win32
I did a tiny viewer by my own:
https://github.com/enexusde/Delphi/wiki/TinyLog

Resources