5

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

Username 2020
  • 101
  • 2
  • 10
  • 1
    Update for anyone interested: I found an npm package called node-pty and I think I'm getting somewhere – Username 2020 Aug 13 '20 at 17:59
  • Is there a tutorial for this for a web app? – zero_cool Apr 30 '21 at 02:34
  • @zero_cool A web app is quite different from an electron app because web apps don't have access to node.js apis which is what allows this to work. Your best bet for getting a terminal to work in the web browser is with an ssh connection or manually transmitting packets with websockets to a remote server – Username 2020 May 27 '21 at 04:11
  • It's definitely possible for a web app to be able to make requests to a node API. Is there a different type of access that's required. If I run a node server on one port, I can make requests to that port from the UI of the webapp (clicking a submit button etc) – zero_cool May 28 '21 at 18:44

2 Answers2

6

The following video was helpful for me. Shortly, you need to :

  1. install node-pty and electron-rebuild packages (additional to the xterm)
  2. 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();
  1. 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
Giorgos Xou
  • 1,461
  • 1
  • 13
  • 32
Orozbek Askarov
  • 126
  • 1
  • 9
  • 2
    Well this is... Interesting, that video that helped you was my video that I made after finding the solution, I do however appreciate the time you put in to this post, the solutions for common errors, and the xterm terminal fit add-on. Thanks anyways. – Username 2020 Jan 24 '21 at 05:53
  • lol, then thank you. Your video was really helpful. Good luck to your YouTube Channel. – Orozbek Askarov Jan 25 '21 at 19:00
  • I did everything but conpty.node seems to be compiled using NODE_MODULE_VERSION 98 and it requires NODE_MODULE_VERSION 99. electron-build doesn't help with this – Ethicist Jan 19 '22 at 23:10
  • A similar error occurs on the prototype you've supplied too. – Ethicist Jan 19 '22 at 23:50
4

I figured it out, code on github: https://github.com/77Z/electron-local-terminal-prototype

Username 2020
  • 101
  • 2
  • 10