Re: Spawning a console in Windows (similar to forkpty on linux)
On Saturday, 9 May 2015 at 23:32:49 UTC, Adam D. Ruppe wrote: On Saturday, 9 May 2015 at 13:00:01 UTC, wobbles wrote: On Linux, I'm able to edit a file descriptor after I've created it to tell it to read/write asynchronously, I cant seem to find anything similar on windows however. Asynchronous I/O on Windows is called "Overlapped I/O". It is a bit involved to use though, especially since D by default doesn't come with all the necessary headers. You can download the win32 api bindings or you can just declare the bits as needed. My terminal emulator uses overlapped I/O and a spawned process (and on Linux, it uses forkpty!) to talk to ssh on Windows. https://github.com/adamdruppe/terminal-emulator/blob/master/terminalemulator.d I had to write a function to make an async pipe, then spawn a process using them, then get and send data. I also declared all the needed functions myself. A lot of code to go through but it is a working example... a few things to look for are MyCreatePipeEx, CreateProcess, the word 'overlapped', ReadFileEx, and the simpledisplay.d library it imports also uses SleepEx which lets other things trigger. Thanks adam, this is very helpful!
Re: Spawning a console in Windows (similar to forkpty on linux)
On Saturday, 9 May 2015 at 13:00:01 UTC, wobbles wrote: My windows knowledge isnt marvelous, but I believe I'll need the interpreter attached. If you only need the interpreter, pipeProcess should be fine, it's a normal program like anything else, just interactive.
Re: Spawning a console in Windows (similar to forkpty on linux)
On Saturday, 9 May 2015 at 13:00:01 UTC, wobbles wrote: Just as an example of running cmd through std.process, running this on my system: auto pipes = pipeShell("cmd.exe"); write(pipes.stdout.readln); write(pipes.stdout.readln); write(pipes.stdout.readln); return; will print ` Microsoft Windows [Version 6.3.9600] (c) 2013 Microsoft Corporation. All rights reserved. ` and then exits. However, adding another "write" line before the return; will cause the program to hang there, waiting for the cmd.exe process to flush it's next line. I guess, the last (prompt) line is properly flushed, it just doesn't have EOL, that's why readln won't return it. See if stdout has a method to read/peek whatever data it has without waiting for EOL.
Re: Spawning a console in Windows (similar to forkpty on linux)
On Saturday, 9 May 2015 at 13:00:01 UTC, wobbles wrote: On Linux, I'm able to edit a file descriptor after I've created it to tell it to read/write asynchronously, I cant seem to find anything similar on windows however. Asynchronous I/O on Windows is called "Overlapped I/O". It is a bit involved to use though, especially since D by default doesn't come with all the necessary headers. You can download the win32 api bindings or you can just declare the bits as needed. My terminal emulator uses overlapped I/O and a spawned process (and on Linux, it uses forkpty!) to talk to ssh on Windows. https://github.com/adamdruppe/terminal-emulator/blob/master/terminalemulator.d I had to write a function to make an async pipe, then spawn a process using them, then get and send data. I also declared all the needed functions myself. A lot of code to go through but it is a working example... a few things to look for are MyCreatePipeEx, CreateProcess, the word 'overlapped', ReadFileEx, and the simpledisplay.d library it imports also uses SleepEx which lets other things trigger.
Re: Spawning a console in Windows (similar to forkpty on linux)
On Saturday, 9 May 2015 at 18:19:16 UTC, Baz wrote: You need a loop that run until the PID is invalid. You could also call WaitForSingleObject on the process handle https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032%28v=vs.85%29.aspx The HANDLE it expects can be gotten from std.process with this http://dlang.org/phobos/std_process.html#osHandle But then you'll block for it to end so it probably isn't what you really want...
Re: Spawning a console in Windows (similar to forkpty on linux)
On Saturday, 9 May 2015 at 13:01:27 UTC, wobbles wrote: On Saturday, 9 May 2015 at 13:00:01 UTC, wobbles wrote: On Saturday, 9 May 2015 at 12:48:16 UTC, Kagamin wrote: On Saturday, 9 May 2015 at 12:26:58 UTC, wobbles wrote: What I mean is, if the cmd.exe hasnt flushed it's output, my cmdPid.stdout.readln (or whatever) will block until it does. I dont really want this. Are you sure cmd is the culprit? It should have sensible buffering. Also do you want just a console window or also a command interpreter attached to it? My windows knowledge isnt marvelous, but I believe I'll need the interpreter attached. Just as an example of running cmd through std.process, running this on my system: auto pipes = pipeShell("cmd.exe"); write(pipes.stdout.readln); write(pipes.stdout.readln); write(pipes.stdout.readln); return; will print ` Microsoft Windows [Version 6.3.9600] (c) 2013 Microsoft Corporation. All rights reserved. ` and then exits. However, adding another "write" line before the return; will cause the program to hang there, waiting for the cmd.exe process to flush it's next line. On Linux, I'm able to edit a file descriptor after I've created it to tell it to read/write asynchronously, I cant seem to find anything similar on windows however. Spoke too soon. Looks like this is what I need: http://www.codeproject.com/Articles/534/An-Introduction-to-Processes-Asynchronous-Process You need a loop that run until the PID is invalid. something like: --- while(true) { Thread.sleep(dur!"msecs"(10)); // operation on i/o streams write(pipes.stdout.readln); if (pipes.pid.tryWait.terminated) break; } --- also note that the piped process needs its whole output to be read before it terminates, otherwise it can stick (never ends).
Re: Spawning a console in Windows (similar to forkpty on linux)
On Saturday, 9 May 2015 at 13:00:01 UTC, wobbles wrote: On Saturday, 9 May 2015 at 12:48:16 UTC, Kagamin wrote: On Saturday, 9 May 2015 at 12:26:58 UTC, wobbles wrote: What I mean is, if the cmd.exe hasnt flushed it's output, my cmdPid.stdout.readln (or whatever) will block until it does. I dont really want this. Are you sure cmd is the culprit? It should have sensible buffering. Also do you want just a console window or also a command interpreter attached to it? My windows knowledge isnt marvelous, but I believe I'll need the interpreter attached. Just as an example of running cmd through std.process, running this on my system: auto pipes = pipeShell("cmd.exe"); write(pipes.stdout.readln); write(pipes.stdout.readln); write(pipes.stdout.readln); return; will print ` Microsoft Windows [Version 6.3.9600] (c) 2013 Microsoft Corporation. All rights reserved. ` and then exits. However, adding another "write" line before the return; will cause the program to hang there, waiting for the cmd.exe process to flush it's next line. On Linux, I'm able to edit a file descriptor after I've created it to tell it to read/write asynchronously, I cant seem to find anything similar on windows however. Spoke too soon. Looks like this is what I need: http://www.codeproject.com/Articles/534/An-Introduction-to-Processes-Asynchronous-Process
Re: Spawning a console in Windows (similar to forkpty on linux)
On Saturday, 9 May 2015 at 12:48:16 UTC, Kagamin wrote: On Saturday, 9 May 2015 at 12:26:58 UTC, wobbles wrote: What I mean is, if the cmd.exe hasnt flushed it's output, my cmdPid.stdout.readln (or whatever) will block until it does. I dont really want this. Are you sure cmd is the culprit? It should have sensible buffering. Also do you want just a console window or also a command interpreter attached to it? My windows knowledge isnt marvelous, but I believe I'll need the interpreter attached. Just as an example of running cmd through std.process, running this on my system: auto pipes = pipeShell("cmd.exe"); write(pipes.stdout.readln); write(pipes.stdout.readln); write(pipes.stdout.readln); return; will print ` Microsoft Windows [Version 6.3.9600] (c) 2013 Microsoft Corporation. All rights reserved. ` and then exits. However, adding another "write" line before the return; will cause the program to hang there, waiting for the cmd.exe process to flush it's next line. On Linux, I'm able to edit a file descriptor after I've created it to tell it to read/write asynchronously, I cant seem to find anything similar on windows however.
Re: Spawning a console in Windows (similar to forkpty on linux)
On Saturday, 9 May 2015 at 12:26:58 UTC, wobbles wrote: What I mean is, if the cmd.exe hasnt flushed it's output, my cmdPid.stdout.readln (or whatever) will block until it does. I dont really want this. Are you sure cmd is the culprit? It should have sensible buffering. Also do you want just a console window or also a command interpreter attached to it?
Re: Spawning a console in Windows (similar to forkpty on linux)
On Saturday, 9 May 2015 at 12:25:32 UTC, wobbles wrote: On Saturday, 9 May 2015 at 12:16:52 UTC, Rikki Cattermole wrote: On 10/05/2015 12:13 a.m., wobbles wrote: This isn't specifically a D question, but seeing as it's for a D library I figure it can go here :) On Windows, I want to be able to spawn a console and then interact with its stdin/out asynchronously, similar to how forkpty [1] works on linux. I'm improving my dexpect library [2] to work with windows machines and this bit has me stumped. There doesnt seem to be much info about it that I can find (though my google-fu mightn't be good enough!!) I'm sure theres someone here who knows something? Thanks! [1] http://linux.die.net/man/3/forkpty [2] https://github.com/grogancolin/dexpect Did you try creating a new process which is cmd? Because std.process should be able to handle the IO part. I have, but they all block i/o and so I cant continually read from its output :/ What I mean is, if the cmd.exe hasnt flushed it's output, my cmdPid.stdout.readln (or whatever) will block until it does. I dont really want this. I guess I need to make another thread to do this so I wont block the main thread?
Re: Spawning a console in Windows (similar to forkpty on linux)
On Saturday, 9 May 2015 at 12:16:52 UTC, Rikki Cattermole wrote: On 10/05/2015 12:13 a.m., wobbles wrote: This isn't specifically a D question, but seeing as it's for a D library I figure it can go here :) On Windows, I want to be able to spawn a console and then interact with its stdin/out asynchronously, similar to how forkpty [1] works on linux. I'm improving my dexpect library [2] to work with windows machines and this bit has me stumped. There doesnt seem to be much info about it that I can find (though my google-fu mightn't be good enough!!) I'm sure theres someone here who knows something? Thanks! [1] http://linux.die.net/man/3/forkpty [2] https://github.com/grogancolin/dexpect Did you try creating a new process which is cmd? Because std.process should be able to handle the IO part. I have, but they all block i/o and so I cant continually read from its output :/
Re: Spawning a console in Windows (similar to forkpty on linux)
On 10/05/2015 12:13 a.m., wobbles wrote: This isn't specifically a D question, but seeing as it's for a D library I figure it can go here :) On Windows, I want to be able to spawn a console and then interact with its stdin/out asynchronously, similar to how forkpty [1] works on linux. I'm improving my dexpect library [2] to work with windows machines and this bit has me stumped. There doesnt seem to be much info about it that I can find (though my google-fu mightn't be good enough!!) I'm sure theres someone here who knows something? Thanks! [1] http://linux.die.net/man/3/forkpty [2] https://github.com/grogancolin/dexpect Did you try creating a new process which is cmd? Because std.process should be able to handle the IO part.