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

Windows Support #30

Merged
merged 60 commits into from
Mar 2, 2013
Merged

Windows Support #30

merged 60 commits into from
Mar 2, 2013

Conversation

peters
Copy link
Contributor

@peters peters commented Dec 19, 2012

Changeset

Added libwinpty in deps/winpty. I've made some minor changes and committed them upstream, but these are not related to the library itself.

Remarks

Only pty.fork() is supported.
Unit tests fails, could somebody care to investigate why?

Demo

git clone https://github.com/chjj/tty.js.git
cd tty.js
npm install
cd node_modules
rd /s /q pty.js
git clone https://github.com/peters/pty.js.git
npm install
cd ../../
node bin/tty.js

And you shall have unicorns!

@peters
Copy link
Contributor Author

peters commented Dec 19, 2012

/cc @chjj @TooTallNate

@chjj
Copy link
Owner

chjj commented Dec 19, 2012

I'm really impressed you got this working on windows, @peters.

@TooTallNate, any thoughts?

I definitely won't be able to maintain the windows code. If anything changes with the pty.js terminal api, I probably won't be able to change it or test it for windows.

@peters, why is term.ready necessary? Would it be possible to just buffer data/writes before the terminal is ready?

@peters
Copy link
Contributor Author

peters commented Dec 19, 2012

@chjj

One could say that having windows support will put severe limitations on what can be achieved on the unix end. Though my initial solution to this is just to throw an exception on methods not supported on windows, such as Terminal.open() and add specific notes in README.md.

As a side note, i'm going to use pty.js in a new project in the nearest future, so if any new functionality is required on the windows side, and its possible to implement i can take of that.

Breakdown on what happens when a new terminal is forked

  1. pty.fork() -> PtyStartProcess
  2. Which in turn starts a new process of winpty-agent.exe
  3. winpty-agent.exe connects to https://github.com/peters/pty.js/blob/master/lib/pty_win.js#L44
  4. When a connection is aknowledged in node we know the terminal ready.

It usually takes around 500 ms because winpty-agent.exe also connects to an internal named pipe: https://github.com/peters/pty.js/blob/master/deps/winpty/libwinpty/winpty.cc#L284

And that's why term.ready() is needed because we need to wait for 4) before its safeto assume a terminal was successfully forked.

So if you could create a socket and block the node event loop some way until winpty-agent is connected to this.dataPipe then we could eliminate term.ready(). I've tried various solutions but they have all been unsuccessfull, but maybe somebody else knows on how this could be achieved.

@chjj
Copy link
Owner

chjj commented Dec 19, 2012

Though my initial solution to this is just to throw an exception on methods not supported on windows

Yeah, that's good. I definitely prefer that.

As a side note, i'm going to use pty.js in a new project in the nearest future, so if any new functionality is required on the windows side, and its possible to implement i can take of that.

Sounds alright.

So if you could create a socket and block the node event loop some way until winpty-agent is connected to this.dataPipe then we could eliminate term.ready(). I've tried various solutions but they have all been unsuccessfull, but maybe somebody else knows on how this could be achieved.

What's wrong with buffering writes to the terminal?

@peters
Copy link
Contributor Author

peters commented Dec 19, 2012

Buffering data/writes is possible, but what about Terminal.resize/Terminal.kill.. these could be defered until the terminal is ready, but what about the other methods? But that might also have side effects as well, thats why i ended up with term.ready()

If you have any genius ideas on how this could be achieved smoothly i'm all ears :)

@chjj
Copy link
Owner

chjj commented Dec 19, 2012

Buffering data/writes is possible, but what about Terminal.resize/Terminal.kill.. these could be defered until the terminal is ready, but what about the other methods? But that might also have side effects as well, thats why i ended up with term.ready()

I'd really prefer buffering writes and deferring any other method. Obviously the downside is .resize/.kill/etc would not necessarily be sync and might cause some problems, but we could actually do both. Keep the 'ready' event, but also buffer if anything is called before the terminal is ready. I do not want to have to change the unix api for any reason.

@peters
Copy link
Contributor Author

peters commented Feb 27, 2013

@TooTallNate any luck getting it running now? ;) checkout test.js

@peters
Copy link
Contributor Author

peters commented Feb 27, 2013

@chjj tested with latest tty.js, works like a charm :)

@TooTallNate
Copy link
Collaborator

Ill try to test it out today. Good work!

On Tuesday, February 26, 2013, Peter Rekdal wrote:

@chjj https://github.com/chjj tested with latest tty.js, works like a
charm :)


Reply to this email directly or view it on GitHubhttps://github.com//pull/30#issuecomment-14161432
.

@peters
Copy link
Contributor Author

peters commented Mar 1, 2013

so... how did it go?

@TooTallNate
Copy link
Collaborator

@peters Hey there! So I just tried your code again on Windows XP. It seems like it's getting farther than it was previously, but I still never see anything get printed to the node application.

If I launch the DebugServer first, I see output for the text that I input, but no debug information for anything coming from the cmd.exe:

C:\Documents and Settings\Administrator\Desktop\repos\pty.js>deps\winpty\misc\De
bugServer.py
[55836.317 winpty-agent.exe,p0392,t2908]: Agent starting...
[55836.317 winpty-agent.exe,p0392,t2908]: font #0: X=4 Y=6
[55836.317 winpty-agent.exe,p0392,t2908]: current font: idx=8 X=80 Y=25
[55836.317 winpty-agent.exe,p0392,t2908]: SetConsoleFont call succeeded
[55836.317 winpty-agent.exe,p0392,t2908]: connection to [\\.\pipe\winpty-2492-1-
control], handle == 0x2c
[55836.317 winpty-agent.exe,p0392,t2908]: connection to [\\.\pipe\winpty-data-11
362155836301], handle == 0x38
[55836.332 winpty-agent.exe,p0392,t2908]: CreateProcess: success 0
[55836.332 winpty-agent.exe,p0392,t2908]: Create process error code: 0
[55836.364 winpty-agent.exe,p0392,t2908]: writeInput: 0 bytes
[55852.135 winpty-agent.exe,p0392,t2908]: writeInput: 5 bytes
[55852.135 winpty-agent.exe,p0392,t2908]: scanKeyPress: 5 bytes
[55852.135 winpty-agent.exe,p0392,t2908]: lookupKey
[55852.135 winpty-agent.exe,p0392,t2908]: 100
[55852.135 winpty-agent.exe,p0392,t2908]: 105
[55852.135 winpty-agent.exe,p0392,t2908]: 114
[55852.135 winpty-agent.exe,p0392,t2908]: 13
[55852.135 winpty-agent.exe,p0392,t2908]: 10
[55852.135 winpty-agent.exe,p0392,t2908]: ch: 100 --> node:00000000
[55852.135 winpty-agent.exe,p0392,t2908]: scanKeyPress: 4 bytes
[55852.135 winpty-agent.exe,p0392,t2908]: lookupKey
[55852.135 winpty-agent.exe,p0392,t2908]: 105
[55852.135 winpty-agent.exe,p0392,t2908]: 114
[55852.135 winpty-agent.exe,p0392,t2908]: 13
[55852.135 winpty-agent.exe,p0392,t2908]: 10
[55852.135 winpty-agent.exe,p0392,t2908]: ch: 105 --> node:00000000
[55852.135 winpty-agent.exe,p0392,t2908]: scanKeyPress: 3 bytes
[55852.135 winpty-agent.exe,p0392,t2908]: lookupKey
[55852.135 winpty-agent.exe,p0392,t2908]: 114
[55852.135 winpty-agent.exe,p0392,t2908]: 13
[55852.135 winpty-agent.exe,p0392,t2908]: 10
[55852.135 winpty-agent.exe,p0392,t2908]: ch: 114 --> node:00000000
[55852.135 winpty-agent.exe,p0392,t2908]: scanKeyPress: 2 bytes
[55852.135 winpty-agent.exe,p0392,t2908]: lookupKey
[55852.135 winpty-agent.exe,p0392,t2908]: 13
[55852.135 winpty-agent.exe,p0392,t2908]: 10
[55852.135 winpty-agent.exe,p0392,t2908]: ch: 13 --> node:00000000
[55852.135 winpty-agent.exe,p0392,t2908]: scanKeyPress: 1 bytes
[55852.135 winpty-agent.exe,p0392,t2908]: lookupKey
[55852.135 winpty-agent.exe,p0392,t2908]: 10
[55852.135 winpty-agent.exe,p0392,t2908]: ch: 10 --> node:00000000
[55890.766 winpty-agent.exe,p0392,t2908]: writeInput: 6 bytes
[55890.766 winpty-agent.exe,p0392,t2908]: scanKeyPress: 6 bytes
[55890.766 winpty-agent.exe,p0392,t2908]: lookupKey
[55890.766 winpty-agent.exe,p0392,t2908]: 116
[55890.766 winpty-agent.exe,p0392,t2908]: 101
[55890.766 winpty-agent.exe,p0392,t2908]: 115
[55890.766 winpty-agent.exe,p0392,t2908]: 116
[55890.766 winpty-agent.exe,p0392,t2908]: 13
[55890.766 winpty-agent.exe,p0392,t2908]: 10
[55890.766 winpty-agent.exe,p0392,t2908]: ch: 116 --> node:00000000
[55890.766 winpty-agent.exe,p0392,t2908]: scanKeyPress: 5 bytes
[55890.766 winpty-agent.exe,p0392,t2908]: lookupKey
[55890.766 winpty-agent.exe,p0392,t2908]: 101
[55890.766 winpty-agent.exe,p0392,t2908]: 115
[55890.766 winpty-agent.exe,p0392,t2908]: 116
[55890.766 winpty-agent.exe,p0392,t2908]: 13
[55890.766 winpty-agent.exe,p0392,t2908]: 10
[55890.766 winpty-agent.exe,p0392,t2908]: ch: 101 --> node:00000000
[55890.766 winpty-agent.exe,p0392,t2908]: scanKeyPress: 4 bytes
[55890.781 winpty-agent.exe,p0392,t2908]: lookupKey
[55890.781 winpty-agent.exe,p0392,t2908]: 115
[55890.781 winpty-agent.exe,p0392,t2908]: 116
[55890.781 winpty-agent.exe,p0392,t2908]: 13
[55890.781 winpty-agent.exe,p0392,t2908]: 10
[55890.781 winpty-agent.exe,p0392,t2908]: ch: 115 --> node:00000000
[55890.781 winpty-agent.exe,p0392,t2908]: scanKeyPress: 3 bytes
[55890.781 winpty-agent.exe,p0392,t2908]: lookupKey
[55890.781 winpty-agent.exe,p0392,t2908]: 116
[55890.781 winpty-agent.exe,p0392,t2908]: 13
[55890.781 winpty-agent.exe,p0392,t2908]: 10
[55890.781 winpty-agent.exe,p0392,t2908]: ch: 116 --> node:00000000
[55890.781 winpty-agent.exe,p0392,t2908]: scanKeyPress: 2 bytes
[55890.781 winpty-agent.exe,p0392,t2908]: lookupKey
[55890.781 winpty-agent.exe,p0392,t2908]: 13
[55890.781 winpty-agent.exe,p0392,t2908]: 10
[55890.781 winpty-agent.exe,p0392,t2908]: ch: 13 --> node:00000000
[55890.781 winpty-agent.exe,p0392,t2908]: scanKeyPress: 1 bytes
[55890.781 winpty-agent.exe,p0392,t2908]: lookupKey
[55890.781 winpty-agent.exe,p0392,t2908]: 10
[55890.781 winpty-agent.exe,p0392,t2908]: ch: 10 --> node:00000000

@peters
Copy link
Contributor Author

peters commented Mar 1, 2013

Could you try by specific the absolute path to cmd.exe? I'm having discussion with richard regarding some issues related to Windows XP. Try the following code:

var pty = require('./');

var term = pty.fork('C:\\Windows\system32\cmd.exe', [], {
  name: 'Windows Shell',
  cols: 80,
  rows: 30,
  cwd: process.env.HOME,
  env: process.env,
  debug: true
});

process.stdin.pipe(term);
process.stdin.resume();

term.pipe(process.stdout)

@TooTallNate
Copy link
Collaborator

@peters Seemingly the same result... I'll try Windows 7 in a bit to see if I get varying results.

@peters
Copy link
Contributor Author

peters commented Mar 1, 2013

Strange, let me know if you get it working on 7.. I'm testing on Windows XP SP3 and Windows 7 SP 1.. if it does not work, i'll do a fresh install of both OS and see if i can try to reproduce the problem.. because, this is very odd..

@TooTallNate
Copy link
Collaborator

@peters You know, I get basically the same result on Windows 7 as well... I'm really not sure what I'm doing wrong. Could you maybe make a screencast or something showing all the steps to get it running properly?

@peters
Copy link
Contributor Author

peters commented Mar 2, 2013

Sure i could do that, but could you try one last thing first?

git clone git://github.com/chjj/tty.js.git
cd tty.js
npm install
cd node_modules
git clone https://github.com/peters/pty.js.git
git submodule update --init --recursive
cd pty.js
npm install
cd tty.js
node bin/tty.js

Tested with node v0.8.21

[tty.js] Listening on port 8080.

  1. Open webbrowser at http://localhost:8080 -> Might need to click open terminal a couple of times.
  2. Edit lib/tty.js at line 432 from conf.shell to "cmd.exe"
  3. Restart tty.js
  4. Open webbrowser at http://localhost:8080 and you should see a valid windows shell.
  5. You shall see unicorns.

Please note that you should install msysgit environment if you want to the first test to work since tty.js
by default forks a new bash terminal.

I've followed these steps myself, like 10 minutes ago on a fresh Windows 7 installation and it worked great :)

@peters
Copy link
Contributor Author

peters commented Mar 2, 2013

My test environment is VS 2012 express edition with Windows 7 SP 1 with latest patches installed.

@TooTallNate
Copy link
Collaborator

@peters Doing your steps above worked :)

Screen Shot 2013-03-01 at 9 03 31 PM

This is very exiting!!!

So that said... what's wrong with our standalone test case? I'll have to dig into it I guess. Does running the code you posted in #30 (comment) work for you? It should basically just pass-through everything in the cmd.exe as if there's nothing there.

@peters
Copy link
Contributor Author

peters commented Mar 2, 2013

Awesome! I do not know, but looking at the assertion errors popping up, the windows version of .fork() outputs console data.. Also there seems to be some issues starting node.exe.. see rprichard/winpty#9

TooTallNate added a commit that referenced this pull request Mar 2, 2013
@TooTallNate TooTallNate merged commit 4f640d0 into chjj:master Mar 2, 2013
@TooTallNate
Copy link
Collaborator

@peters I went ahead and merged your code. Partially working windows support is better than no windows support. We can iron out the kinks individually now. Thanks again, this is awesome stuff!

@peters
Copy link
Contributor Author

peters commented Mar 4, 2013

Awesome! np :)

@skol63
Copy link

skol63 commented Mar 12, 2013

Found a problem when environement isn't passed correctly, this possible also cause problem mentioned above(you should specify full path to cmd.exe) since env.path isn't passed correctly.
env variables list joint via space in lib/win_pty.js(49) and passed to deps/winpty/libwinpty/winpty.cc(473) where I found comment about how it should be formed.
from http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx :
An environment block consists of a null-terminated block of null-terminated strings. Each string is in the following form:
name=value\0
I'm not so good with C for propose needed changes, so can't make pull request.
BTW: set command output in pty console:
D:\Program Files\nodejs>set

COMSPEC=D:\windows\system32\cmd.exe
GENESIS_HOME=D:\Program Files\Acucorp\Acucbl813\AcuGT PATH=D:\Program Files\Acucorp\Acucbl813\AcuGT\bin;D:\windows\system32; TERM=Windows Shell
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS
PROMPT=$P$G

as you can see PATH, TERM and GENESIS_HOME variables joined into one

@peters
Copy link
Contributor Author

peters commented Mar 12, 2013

Thank you for reporting the issue, i'll try to find some time this week and commit a patch :)

ddm pushed a commit to ddm/pty.js that referenced this pull request Nov 8, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants