Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to start terminal process: CreateProcess failed #203

Closed
zhengtulymGh opened this issue Jun 19, 2018 · 1 comment
Closed

Unable to start terminal process: CreateProcess failed #203

zhengtulymGh opened this issue Jun 19, 2018 · 1 comment

Comments

@zhengtulymGh
Copy link

zhengtulymGh commented Jun 19, 2018

Environment details

  • OS: windows
  • OS version: Windows 7 Ultimate
  • node-pty version: 0.7.2

Issue description

why absolute path don't work for me 197

my app.js

var express = require('express');
var app = express();
var expressWs = require('express-ws')(app);
var os = require('os');
var pty = require('node-pty');

const fs = require('fs');

const server = require('./config/env');
const nodeEnv = server.env;
const port = nodeEnv.port;

var terminals = {},
    logs = {};

console.log('os.platform()', os.platform())
var shell = os.platform() === 'win32' ? 'C:\\Windows\\System32\\cmd.exe' : 'bash';  //'cmd.exe'  don't work either

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  // res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

app.get('/', function(req, res){
  // res.sendFile(__dirname + '/index.html');
  console.log('get /')
  fs.readFile(__dirname + '/index.html', "utf8", (err, file) => {
    if (err) {
      next()
    } else {
      res.status(200).send(file);
    }
  });
});

app.post('/terminals', function (req, res) {
  console.log('req.query.cols', req.query.cols)
  console.log('req.query.rows', req.query.rows)
  var cols = parseInt(req.query.cols),
      rows = parseInt(req.query.rows),
      term = pty.spawn(shell, [], {
        name: 'xterm-color',
        cols: cols || 80,
        rows: rows || 24,
        cwd: process.env.PWD,
        env: process.env
      });

  console.log('Created terminal with PID: ' + term.pid);
  terminals[term.pid] = term;
  logs[term.pid] = '';
  term.on('data', function(data) {
    logs[term.pid] += data;
  });
  res.send(term.pid.toString());
  res.end();
});

app.post('/terminals/:pid/size', function (req, res) {
  var pid = parseInt(req.params.pid),
      cols = parseInt(req.query.cols),
      rows = parseInt(req.query.rows),
      term = terminals[pid];

  term.resize(cols, rows);
  console.log('Resized terminal ' + pid + ' to ' + cols + ' cols and ' + rows + ' rows.');
  res.end();
});

app.ws('/terminals/:pid', function (ws, req) {
  var term = terminals[parseInt(req.params.pid)];
  console.log('Connected to terminal ' + term.pid);
  ws.send(logs[term.pid]);
  console.log('term', term)
  console.log('logs', logs)

  term.on('data', function(data) {
    console.log('on data', data)
    try {
      ws.send(data);
    } catch (ex) {
      // The WebSocket is not open, ignore
    }
  });
  ws.on('message', function(msg) {
    console.log('on message', msg)
    term.write(msg);
  });
  ws.on('close', function () {
    term.kill();
    console.log('Closed terminal ' + term.pid);
    // Clean things up
    delete terminals[term.pid];
    delete logs[term.pid];
  });
});

// var port = process.env.PORT || 6666,
var host = os.platform() === 'win32' ? '127.0.0.1' : '0.0.0.0';

console.log('App listening to http://' + host + ':' + port);
// app.listen(port, host);

app.listen(port, host, err => {
  console.log(err || '监听端口:' + port); // port is 6600
});

my web-termimal

import * as Terminal from '../build/xterm';
import * as attach from '../build/addons/attach/attach';
import * as fit from '../build/addons/fit/fit';
import * as fullscreen from '../build/addons/fullscreen/fullscreen';
import * as search from '../build/addons/search/search';
import * as webLinks from '../build/addons/webLinks/webLinks';
import * as winptyCompat from '../build/addons/winptyCompat/winptyCompat';


Terminal.applyAddon(attach);
Terminal.applyAddon(fit);
Terminal.applyAddon(fullscreen);
Terminal.applyAddon(search);
Terminal.applyAddon(webLinks);
Terminal.applyAddon(winptyCompat);


var term,
    protocol,
    socketURL,
    socket,
    pid;

var terminalContainer = document.getElementById('terminal-container'),
    actionElements = {
      findNext: document.querySelector('#find-next'),
      findPrevious: document.querySelector('#find-previous')
    },
    paddingElement = document.getElementById('padding');

const serverUrl = 'http://127.0.0.1:6600'

function setPadding() {
  term.element.style.padding = parseInt(paddingElement.value, 10).toString() + 'px';
  term.fit();
}

paddingElement.addEventListener('change', setPadding);

actionElements.findNext.addEventListener('keypress', function (e) {
  if (e.key === "Enter") {
    e.preventDefault();
    term.findNext(actionElements.findNext.value);
  }
});
actionElements.findPrevious.addEventListener('keypress', function (e) {
  if (e.key === "Enter") {
    e.preventDefault();
    term.findPrevious(actionElements.findPrevious.value);
  }
});

createTerminal();

function createTerminal() {
  // Clean terminal
  while (terminalContainer.children.length) {
    terminalContainer.removeChild(terminalContainer.children[0]);
  }
  term = new Terminal({});
  window.term = term;  // Expose `term` to window for debugging purposes
  term.on('resize', function (size) {
    if (!pid) {
      return;
    }
    var cols = size.cols,
        rows = size.rows,
        url = serverUrl + '/terminals/' + pid + '/size?cols=' + cols + '&rows=' + rows;

    fetch(url, {method: 'POST'});
  });
  protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://';
  socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/terminals/';

  term.open(terminalContainer);
  term.winptyCompatInit();
  term.webLinksInit();
  term.fit();
  term.focus();

  // fit is called within a setTimeout, cols and rows need this.
  setTimeout(function () {
    initOptions(term);
    document.getElementById(`opt-cols`).value = term.cols;
    document.getElementById(`opt-rows`).value = term.rows;
    paddingElement.value = 0;

    // Set terminal size again to set the specific dimensions on the demo
    updateTerminalSize();

    fetch(serverUrl + '/terminals?cols=' + term.cols + '&rows=' + term.rows, {method: 'POST'}).then(function (res) {

      res.text().then(function (processId) {
        pid = processId;
        socketURL += processId;
        socket = new WebSocket(socketURL);
        socket.onopen = runRealTerminal;
        socket.onclose = runFakeTerminal;
        socket.onerror = runFakeTerminal;
      });
    });
  }, 0);
}

function runRealTerminal() {
  term.attach(socket);
  term._initialized = true;
}

function runFakeTerminal() {
  if (term._initialized) {
    return;
  }

  term._initialized = true;

  var shellprompt = '$ ';

  term.prompt = function () {
    term.write('\r\n' + shellprompt);
  };

  term.writeln('Welcome to xterm.js');
  term.writeln('This is a local terminal emulation, without a real terminal in the back-end.');
  term.writeln('Type some keys and commands to play around.');
  term.writeln('');
  term.prompt();

  term.on('key', function (key, ev) {
    var printable = (
      !ev.altKey && !ev.altGraphKey && !ev.ctrlKey && !ev.metaKey
    );

    if (ev.keyCode == 13) {
      term.prompt();
    } else if (ev.keyCode == 8) {
     // Do not delete the prompt
      if (term.x > 2) {
        term.write('\b \b');
      }
    } else if (printable) {
      term.write(key);
    }
  });

  term.on('paste', function (data, ev) {
    term.write(data);
  });
}

function initOptions(term) {
  var blacklistedOptions = [
    // Internal only options
    'cancelEvents',
    'convertEol',
    'debug',
    'handler',
    'screenKeys',
    'termName',
    'useFlowControl',
    // Complex option
    'theme',
    // Only in constructor
    'rendererType'
  ];
  var stringOptions = {
    bellSound: null,
    bellStyle: ['none', 'sound'],
    cursorStyle: ['block', 'underline', 'bar'],
    experimentalCharAtlas: ['none', 'static', 'dynamic'],
    fontFamily: null,
    fontWeight: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'],
    fontWeightBold: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900']
  };
  var options = Object.keys(term.options);
  var booleanOptions = [];
  var numberOptions = [];
  options.filter(o => blacklistedOptions.indexOf(o) === -1).forEach(o => {
    switch (typeof term.getOption(o)) {
      case 'boolean':
        booleanOptions.push(o);
        break;
      case 'number':
        numberOptions.push(o);
        break;
      default:
        if (Object.keys(stringOptions).indexOf(o) === -1) {
          console.warn(`Unrecognized option: "${o}"`);
        }
    }
  });

  var html = '';
  html += '<div class="option-group">';
  booleanOptions.forEach(o => {
    html += `<div class="option"><label><input id="opt-${o}" type="checkbox" ${term.getOption(o) ? 'checked' : ''}/> ${o}</label></div>`;
  });
  html += '</div><div class="option-group">';
  numberOptions.forEach(o => {
    html += `<div class="option"><label>${o} <input id="opt-${o}" type="number" value="${term.getOption(o)}"/></label></div>`;
  });
  html += '</div><div class="option-group">';
  Object.keys(stringOptions).forEach(o => {
    if (stringOptions[o]) {
      html += `<div class="option"><label>${o} <select id="opt-${o}">${stringOptions[o].map(v => `<option ${term.getOption(o) === v ? 'selected' : ''}>${v}</option>`).join('')}</select></label></div>`;
    } else {
      html += `<div class="option"><label>${o} <input id="opt-${o}" type="text" value="${term.getOption(o)}"/></label></div>`
    }
  });
  html += '</div>';

  var container = document.getElementById('options-container');
  container.innerHTML = html;

  // Attach listeners
  booleanOptions.forEach(o => {
    var input = document.getElementById(`opt-${o}`);
    input.addEventListener('change', () => {
      console.log('change', o, input.checked);
      term.setOption(o, input.checked);
    });
  });
  numberOptions.forEach(o => {
    var input = document.getElementById(`opt-${o}`);
    input.addEventListener('change', () => {
      console.log('change', o, input.value);
      if (o === 'cols' || o === 'rows') {
        updateTerminalSize();
      } else {
        term.setOption(o, parseInt(input.value, 10));
      }
    });
  });
  Object.keys(stringOptions).forEach(o => {
    var input = document.getElementById(`opt-${o}`);
    input.addEventListener('change', () => {
      console.log('change', o, input.value);
      term.setOption(o, input.value);
    });
  });
}

function updateTerminalSize() {
  var cols = parseInt(document.getElementById(`opt-cols`).value, 10);
  var rows = parseInt(document.getElementById(`opt-rows`).value, 10);
  var width = (cols * term.renderer.dimensions.actualCellWidth + term.viewport.scrollBarWidth).toString() + 'px';
  var height = (rows * term.renderer.dimensions.actualCellHeight).toString() + 'px';
  terminalContainer.style.width = width;
  terminalContainer.style.height = height;
  term.fit();
}

error in app.js

os.platform() win32
App listening to http://127.0.0.1:6600
监听端口:6600
req.query.cols 87
req.query.rows 26
Error: Unable to start terminal process: CreateProcess failed
    at new WindowsPtyAgent (E:\project\NodePtyCage\NodePty\node_modules\node-pty\lib\windowsPtyAgent.js:25:24)
    at new WindowsTerminal (E:\project\NodePtyCage\NodePty\node_modules\node-pty\lib\windowsTerminal.js:45:24)
    at Object.spawn (E:\project\NodePtyCage\NodePty\node_modules\node-pty\lib\index.js:27:12)
    at E:\project\NodePtyCage\NodePty\app.js:59:18
    at Layer.handle [as handle_request] (E:\project\NodePtyCage\NodePty\node_modules\express\lib\router\layer.js:95:5)
    at next (E:\project\NodePtyCage\NodePty\node_modules\express\lib\router\route.js:137:13)
    at Route.dispatch (E:\project\NodePtyCage\NodePty\node_modules\express\lib\router\route.js:112:3)
    at Layer.handle [as handle_request] (E:\project\NodePtyCage\NodePty\node_modules\express\lib\router\layer.js:95:5)
    at E:\project\NodePtyCage\NodePty\node_modules\express\lib\router\index.js:281:22
    at Function.process_params (E:\project\NodePtyCage\NodePty\node_modules\express\lib\router\index.js:335:12)
@Tyriar
Copy link
Member

Tyriar commented Jun 19, 2018

What paths work and what doesn't? Is this #112?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants