www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - capturing process output on windows

reply "Carlos Santander B." <csantander619 gmail.com> writes:
What's the correct way of capturing a process output on Windows? I found 
a piece of code on the net, and I tried it, but since I haven't worked 
with pipes before, I don't know what's going on. Anyway, here's what I'm 
trying (using the core32 library):

//-------------------------------------------
//code found in
//http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20682069.html

void main()
{
     char [] stdoutname=r"\\.\pipe\my_output_tmp",
         stderrname=r"\\.\pipe\my_error_tmp",
         stdinname=r"\\.\pipe\my_input_tmp";
     Stream fstderr, fstdout, fstdin;
     HANDLE hstderr, hstdout, hstdin;
     HANDLE outstreamhandle, errstreamhandle, instreamhandle;
     char * pOutputFile=toStringz(stdoutname), 
pInputFile=toStringz(stdinname);

     SECURITY_ATTRIBUTES SecAttrs;
     SecAttrs.nLength=SECURITY_ATTRIBUTES.sizeof;
     SecAttrs.bInheritHandle=true;

     outstreamhandle = CreateNamedPipeA(
         pOutputFile,
         PIPE_ACCESS_DUPLEX,
         PIPE_TYPE_BYTE | PIPE_WAIT,
         PIPE_UNLIMITED_INSTANCES,
         8192,
         8192,
         10000,
         &SecAttrs);

     assert(outstreamhandle!=INVALID_HANDLE_VALUE);

     hstdout = CreateFileA(
         pOutputFile,
         GENERIC_READ | GENERIC_WRITE,
         FILE_SHARE_READ | FILE_SHARE_WRITE,
         &SecAttrs,
         CREATE_ALWAYS,
         FILE_ATTRIBUTE_TEMPORARY,
         null );

     assert(hstdout!=INVALID_HANDLE_VALUE);

    instreamhandle= CreateNamedPipeA(
           pInputFile,
         PIPE_ACCESS_DUPLEX,
         PIPE_TYPE_BYTE | PIPE_WAIT,
         PIPE_UNLIMITED_INSTANCES,
         8192,
         8192,
         10000,
         &SecAttrs);

     assert(instreamhandle!=INVALID_HANDLE_VALUE);

     hstdin = CreateFileA(
          pInputFile,
          GENERIC_READ | GENERIC_WRITE,
          FILE_SHARE_READ | FILE_SHARE_WRITE,
          &SecAttrs,
          OPEN_ALWAYS,
          FILE_ATTRIBUTE_TEMPORARY,
          null );

     assert(hstdin!=INVALID_HANDLE_VALUE);

     STARTUPINFOA sui;
     sui.cb          = STARTUPINFOA.sizeof;
     sui.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
     sui.wShowWindow = SW_HIDE;
     sui.hStdOutput  = hstdout;
     sui.hStdInput   = hstdin;

     PROCESS_INFORMATION pi;
     int res = CreateProcessA(null,
         "dir",
         null,
         null,
         true,
         CREATE_NEW_CONSOLE | REALTIME_PRIORITY_CLASS,
         null,
         null,
         &sui,
         &pi);

     DWORD size;
     size = GetFileSize(outstreamhandle, null);
     printf("%d\n", size);
     size = GetFileSize(hstdout, null);
     printf("%d\n", size);
     size = GetFileSize(instreamhandle, null);
     printf("%d\n", size);
     size = GetFileSize(hstdin, null);
     printf("%d\n", size);
     assert (size != INVALID_FILE_SIZE);

     /*
     fstdout=new BufferedFile(new File(cast(std.stream.HANDLE) 
outstreamhandle, FileMode.In | FileMode.Out ));
     foreach(char[] ln;fstdout)
         stdout.writeLine(ln);
     */

     /*
     fstdin=new BufferedFile(new File(cast(std.stream.HANDLE) 
instreamhandle, FileMode.In | FileMode.Out));
     foreach(char[] ln;fstdin)
         stdout.writeLine(ln);
     */
}
//-------------------------------------------

All asserts pass. All sizes return 0. Obviosly, even in an empty 
directory, "dir" outputs something.

Eventually, I'd like to do what's commented out.

BTW, I've never worked with pipes before on linux, but I also found some 
code to do the same, and it's unbelievably easy. When/if I get this 
Windows thing sorted out (a couple of days, maybe?) I'll release the 
code for anyone in need of it.

-- 
Carlos Santander Bernal

JP2, you'll always live in our minds
Apr 17 2005
next sibling parent reply "Andrew Fedoniouk" <news terrainformatica.com> writes:
It should not be so complicated....

Read this:
http://www.developersdomain.com/vb/articles/redirectpipe.htm
Or this:
http://support.microsoft.com/kb/q173085/

Funny, google returns VB links mostly.... 
Apr 17 2005
parent "Carlos Santander B." <csantander619 gmail.com> writes:
Andrew Fedoniouk wrote:
 It should not be so complicated....
 
 Read this:
 http://www.developersdomain.com/vb/articles/redirectpipe.htm
 Or this:
 http://support.microsoft.com/kb/q173085/
 
 Funny, google returns VB links mostly.... 
 
 
Thanks for that. It seems to work. Well, sort of, I still have a couple of things to check. -- Carlos Santander Bernal JP2, you'll always live in our minds
Apr 18 2005
prev sibling next sibling parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/14470
news://news.digitalmars.com:119/cscp40$pee$1 digitaldaemon.com

I posted this earlier.  It's popen for Windows, which is probably that 
"unbelievably easy" method you mentioned.  Syntax is the same, or you 
cna use the ProcessStream implementation.

-[Unknown]


 What's the correct way of capturing a process output on Windows? I found 
 a piece of code on the net, and I tried it, but since I haven't worked 
 with pipes before, I don't know what's going on. Anyway, here's what I'm 
 trying (using the core32 library):
Apr 18 2005
parent "Carlos Santander B." <csantander619 gmail.com> writes:
Unknown W. Brackets wrote:
 http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/14470
 news://news.digitalmars.com:119/cscp40$pee$1 digitaldaemon.com
 
 I posted this earlier.  It's popen for Windows, which is probably that 
 "unbelievably easy" method you mentioned.  Syntax is the same, or you 
 cna use the ProcessStream implementation.
 
 -[Unknown]
 
Thanks. However I'd like to do both reading and writing. What I have so far works that way on linux, and is kinda buggy on Windows. -- Carlos Santander Bernal JP2, you'll always live in our minds
Apr 18 2005
prev sibling next sibling parent "Carlos Santander B." <csantander619 gmail.com> writes:
Carlos Santander B. wrote:
 
 When/if I get this Windows thing sorted out (a couple of days,
 maybe?) I'll release the code for anyone in need of it.
 
It's not like it's really working on Windows, but I've uploaded it to dsource. It's in http://svn.dsource.org/svn/projects/walnut/downloads/some_other_things/ -- Carlos Santander Bernal JP2, you'll always live in our minds
Apr 18 2005
prev sibling next sibling parent David Medlock <nospam nospam.com> writes:
Carlos Santander B. wrote:
 What's the correct way of capturing a process output on Windows? I found 
 a piece of code on the net, and I tried it, but since I haven't worked 
 with pipes before, I don't know what's going on. Anyway, here's what I'm 
 trying (using the core32 library):
 
 //-------------------------------------------
 //code found in
 //http://www.experts-exchange.com/Programming/Programming_Languages/De
phi/Q_20682069.html 
 
 
 void main()
 {
     char [] stdoutname=r"\\.\pipe\my_output_tmp",
         stderrname=r"\\.\pipe\my_error_tmp",
         stdinname=r"\\.\pipe\my_input_tmp";
     Stream fstderr, fstdout, fstdin;
     HANDLE hstderr, hstdout, hstdin;
     HANDLE outstreamhandle, errstreamhandle, instreamhandle;
     char * pOutputFile=toStringz(stdoutname), 
 pInputFile=toStringz(stdinname);
 
     SECURITY_ATTRIBUTES SecAttrs;
     SecAttrs.nLength=SECURITY_ATTRIBUTES.sizeof;
     SecAttrs.bInheritHandle=true;
 
     outstreamhandle = CreateNamedPipeA(
         pOutputFile,
         PIPE_ACCESS_DUPLEX,
         PIPE_TYPE_BYTE | PIPE_WAIT,
         PIPE_UNLIMITED_INSTANCES,
         8192,
         8192,
         10000,
         &SecAttrs);
 
     assert(outstreamhandle!=INVALID_HANDLE_VALUE);
 
     hstdout = CreateFileA(
         pOutputFile,
         GENERIC_READ | GENERIC_WRITE,
         FILE_SHARE_READ | FILE_SHARE_WRITE,
         &SecAttrs,
         CREATE_ALWAYS,
         FILE_ATTRIBUTE_TEMPORARY,
         null );
 
     assert(hstdout!=INVALID_HANDLE_VALUE);
 
    instreamhandle= CreateNamedPipeA(
           pInputFile,
         PIPE_ACCESS_DUPLEX,
         PIPE_TYPE_BYTE | PIPE_WAIT,
         PIPE_UNLIMITED_INSTANCES,
         8192,
         8192,
         10000,
         &SecAttrs);
 
     assert(instreamhandle!=INVALID_HANDLE_VALUE);
 
     hstdin = CreateFileA(
          pInputFile,
          GENERIC_READ | GENERIC_WRITE,
          FILE_SHARE_READ | FILE_SHARE_WRITE,
          &SecAttrs,
          OPEN_ALWAYS,
          FILE_ATTRIBUTE_TEMPORARY,
          null );
 
     assert(hstdin!=INVALID_HANDLE_VALUE);
 
     STARTUPINFOA sui;
     sui.cb          = STARTUPINFOA.sizeof;
     sui.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
     sui.wShowWindow = SW_HIDE;
     sui.hStdOutput  = hstdout;
     sui.hStdInput   = hstdin;
 
     PROCESS_INFORMATION pi;
     int res = CreateProcessA(null,
         "dir",
         null,
         null,
         true,
         CREATE_NEW_CONSOLE | REALTIME_PRIORITY_CLASS,
         null,
         null,
         &sui,
         &pi);
 
     DWORD size;
     size = GetFileSize(outstreamhandle, null);
     printf("%d\n", size);
     size = GetFileSize(hstdout, null);
     printf("%d\n", size);
     size = GetFileSize(instreamhandle, null);
     printf("%d\n", size);
     size = GetFileSize(hstdin, null);
     printf("%d\n", size);
     assert (size != INVALID_FILE_SIZE);
 
     /*
     fstdout=new BufferedFile(new File(cast(std.stream.HANDLE) 
 outstreamhandle, FileMode.In | FileMode.Out ));
     foreach(char[] ln;fstdout)
         stdout.writeLine(ln);
     */
 
     /*
     fstdin=new BufferedFile(new File(cast(std.stream.HANDLE) 
 instreamhandle, FileMode.In | FileMode.Out));
     foreach(char[] ln;fstdin)
         stdout.writeLine(ln);
     */
 }
 //-------------------------------------------
 
 All asserts pass. All sizes return 0. Obviosly, even in an empty 
 directory, "dir" outputs something.
 
 Eventually, I'd like to do what's commented out.
 
 BTW, I've never worked with pipes before on linux, but I also found some 
 code to do the same, and it's unbelievably easy. When/if I get this 
 Windows thing sorted out (a couple of days, maybe?) I'll release the 
 code for anyone in need of it.
 
You can get the source to DManager, which is in Delphi but uses the Win32 API to capture output. Look in MyUtils.pas -David
Apr 18 2005
prev sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
I have some Win32 C code for doing just this.. I reckon I can whip it into  
a stream class or similar, give me a few days...

Regan

On Sun, 17 Apr 2005 17:01:07 -0500, Carlos Santander B.  
<csantander619 gmail.com> wrote:

 What's the correct way of capturing a process output on Windows? I found  
 a piece of code on the net, and I tried it, but since I haven't worked  
 with pipes before, I don't know what's going on. Anyway, here's what I'm  
 trying (using the core32 library):

 //-------------------------------------------
 //code found in
 //http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20682069.html

 void main()
 {
      char [] stdoutname=r"\\.\pipe\my_output_tmp",
          stderrname=r"\\.\pipe\my_error_tmp",
          stdinname=r"\\.\pipe\my_input_tmp";
      Stream fstderr, fstdout, fstdin;
      HANDLE hstderr, hstdout, hstdin;
      HANDLE outstreamhandle, errstreamhandle, instreamhandle;
      char * pOutputFile=toStringz(stdoutname),  
 pInputFile=toStringz(stdinname);

      SECURITY_ATTRIBUTES SecAttrs;
      SecAttrs.nLength=SECURITY_ATTRIBUTES.sizeof;
      SecAttrs.bInheritHandle=true;

      outstreamhandle = CreateNamedPipeA(
          pOutputFile,
          PIPE_ACCESS_DUPLEX,
          PIPE_TYPE_BYTE | PIPE_WAIT,
          PIPE_UNLIMITED_INSTANCES,
          8192,
          8192,
          10000,
          &SecAttrs);

      assert(outstreamhandle!=INVALID_HANDLE_VALUE);

      hstdout = CreateFileA(
          pOutputFile,
          GENERIC_READ | GENERIC_WRITE,
          FILE_SHARE_READ | FILE_SHARE_WRITE,
          &SecAttrs,
          CREATE_ALWAYS,
          FILE_ATTRIBUTE_TEMPORARY,
          null );

      assert(hstdout!=INVALID_HANDLE_VALUE);

     instreamhandle= CreateNamedPipeA(
            pInputFile,
          PIPE_ACCESS_DUPLEX,
          PIPE_TYPE_BYTE | PIPE_WAIT,
          PIPE_UNLIMITED_INSTANCES,
          8192,
          8192,
          10000,
          &SecAttrs);

      assert(instreamhandle!=INVALID_HANDLE_VALUE);

      hstdin = CreateFileA(
           pInputFile,
           GENERIC_READ | GENERIC_WRITE,
           FILE_SHARE_READ | FILE_SHARE_WRITE,
           &SecAttrs,
           OPEN_ALWAYS,
           FILE_ATTRIBUTE_TEMPORARY,
           null );

      assert(hstdin!=INVALID_HANDLE_VALUE);

      STARTUPINFOA sui;
      sui.cb          = STARTUPINFOA.sizeof;
      sui.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
      sui.wShowWindow = SW_HIDE;
      sui.hStdOutput  = hstdout;
      sui.hStdInput   = hstdin;

      PROCESS_INFORMATION pi;
      int res = CreateProcessA(null,
          "dir",
          null,
          null,
          true,
          CREATE_NEW_CONSOLE | REALTIME_PRIORITY_CLASS,
          null,
          null,
          &sui,
          &pi);

      DWORD size;
      size = GetFileSize(outstreamhandle, null);
      printf("%d\n", size);
      size = GetFileSize(hstdout, null);
      printf("%d\n", size);
      size = GetFileSize(instreamhandle, null);
      printf("%d\n", size);
      size = GetFileSize(hstdin, null);
      printf("%d\n", size);
      assert (size != INVALID_FILE_SIZE);

      /*
      fstdout=new BufferedFile(new File(cast(std.stream.HANDLE)  
 outstreamhandle, FileMode.In | FileMode.Out ));
      foreach(char[] ln;fstdout)
          stdout.writeLine(ln);
      */

      /*
      fstdin=new BufferedFile(new File(cast(std.stream.HANDLE)  
 instreamhandle, FileMode.In | FileMode.Out));
      foreach(char[] ln;fstdin)
          stdout.writeLine(ln);
      */
 }
 //-------------------------------------------

 All asserts pass. All sizes return 0. Obviosly, even in an empty  
 directory, "dir" outputs something.

 Eventually, I'd like to do what's commented out.

 BTW, I've never worked with pipes before on linux, but I also found some  
 code to do the same, and it's unbelievably easy. When/if I get this  
 Windows thing sorted out (a couple of days, maybe?) I'll release the  
 code for anyone in need of it.
Apr 18 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
As promised... Tho it should be noted that you cannot simply run "dir"  
with this. it wants an actual executable not a cmd.exe command like "dir".  
However you can run "cmd /c dir" and get a directory listing.

It would be nice if Ben had time to look at it and make sure I have not  
abused Stream ;)

Regan

On Tue, 19 Apr 2005 16:40:55 +1200, Regan Heath <regan netwin.co.nz> wrote:
 I have some Win32 C code for doing just this.. I reckon I can whip it  
 into a stream class or similar, give me a few days...

 Regan

 On Sun, 17 Apr 2005 17:01:07 -0500, Carlos Santander B.  
 <csantander619 gmail.com> wrote:

 What's the correct way of capturing a process output on Windows? I  
 found a piece of code on the net, and I tried it, but since I haven't  
 worked with pipes before, I don't know what's going on. Anyway, here's  
 what I'm trying (using the core32 library):

 //-------------------------------------------
 //code found in
 //http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20682069.html

 void main()
 {
      char [] stdoutname=r"\\.\pipe\my_output_tmp",
          stderrname=r"\\.\pipe\my_error_tmp",
          stdinname=r"\\.\pipe\my_input_tmp";
      Stream fstderr, fstdout, fstdin;
      HANDLE hstderr, hstdout, hstdin;
      HANDLE outstreamhandle, errstreamhandle, instreamhandle;
      char * pOutputFile=toStringz(stdoutname),  
 pInputFile=toStringz(stdinname);

      SECURITY_ATTRIBUTES SecAttrs;
      SecAttrs.nLength=SECURITY_ATTRIBUTES.sizeof;
      SecAttrs.bInheritHandle=true;

      outstreamhandle = CreateNamedPipeA(
          pOutputFile,
          PIPE_ACCESS_DUPLEX,
          PIPE_TYPE_BYTE | PIPE_WAIT,
          PIPE_UNLIMITED_INSTANCES,
          8192,
          8192,
          10000,
          &SecAttrs);

      assert(outstreamhandle!=INVALID_HANDLE_VALUE);

      hstdout = CreateFileA(
          pOutputFile,
          GENERIC_READ | GENERIC_WRITE,
          FILE_SHARE_READ | FILE_SHARE_WRITE,
          &SecAttrs,
          CREATE_ALWAYS,
          FILE_ATTRIBUTE_TEMPORARY,
          null );

      assert(hstdout!=INVALID_HANDLE_VALUE);

     instreamhandle= CreateNamedPipeA(
            pInputFile,
          PIPE_ACCESS_DUPLEX,
          PIPE_TYPE_BYTE | PIPE_WAIT,
          PIPE_UNLIMITED_INSTANCES,
          8192,
          8192,
          10000,
          &SecAttrs);

      assert(instreamhandle!=INVALID_HANDLE_VALUE);

      hstdin = CreateFileA(
           pInputFile,
           GENERIC_READ | GENERIC_WRITE,
           FILE_SHARE_READ | FILE_SHARE_WRITE,
           &SecAttrs,
           OPEN_ALWAYS,
           FILE_ATTRIBUTE_TEMPORARY,
           null );

      assert(hstdin!=INVALID_HANDLE_VALUE);

      STARTUPINFOA sui;
      sui.cb          = STARTUPINFOA.sizeof;
      sui.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
      sui.wShowWindow = SW_HIDE;
      sui.hStdOutput  = hstdout;
      sui.hStdInput   = hstdin;

      PROCESS_INFORMATION pi;
      int res = CreateProcessA(null,
          "dir",
          null,
          null,
          true,
          CREATE_NEW_CONSOLE | REALTIME_PRIORITY_CLASS,
          null,
          null,
          &sui,
          &pi);

      DWORD size;
      size = GetFileSize(outstreamhandle, null);
      printf("%d\n", size);
      size = GetFileSize(hstdout, null);
      printf("%d\n", size);
      size = GetFileSize(instreamhandle, null);
      printf("%d\n", size);
      size = GetFileSize(hstdin, null);
      printf("%d\n", size);
      assert (size != INVALID_FILE_SIZE);

      /*
      fstdout=new BufferedFile(new File(cast(std.stream.HANDLE)  
 outstreamhandle, FileMode.In | FileMode.Out ));
      foreach(char[] ln;fstdout)
          stdout.writeLine(ln);
      */

      /*
      fstdin=new BufferedFile(new File(cast(std.stream.HANDLE)  
 instreamhandle, FileMode.In | FileMode.Out));
      foreach(char[] ln;fstdin)
          stdout.writeLine(ln);
      */
 }
 //-------------------------------------------

 All asserts pass. All sizes return 0. Obviosly, even in an empty  
 directory, "dir" outputs something.

 Eventually, I'd like to do what's commented out.

 BTW, I've never worked with pipes before on linux, but I also found  
 some code to do the same, and it's unbelievably easy. When/if I get  
 this Windows thing sorted out (a couple of days, maybe?) I'll release  
 the code for anyone in need of it.
Apr 19 2005
next sibling parent "Regan Heath" <regan netwin.co.nz> writes:
Err.. I forgot to mention the linux version of this code is _totally_  
untested, in fact I haven't even compiled it.

On Wed, 20 Apr 2005 01:06:15 +1200, Regan Heath <regan netwin.co.nz> wrote:
 As promised... Tho it should be noted that you cannot simply run "dir"
 with this. it wants an actual executable not a cmd.exe command like  
 "dir".
 However you can run "cmd /c dir" and get a directory listing.

 It would be nice if Ben had time to look at it and make sure I have not
 abused Stream ;)

 Regan

 On Tue, 19 Apr 2005 16:40:55 +1200, Regan Heath <regan netwin.co.nz>  
 wrote:
 I have some Win32 C code for doing just this.. I reckon I can whip it
 into a stream class or similar, give me a few days...

 Regan

 On Sun, 17 Apr 2005 17:01:07 -0500, Carlos Santander B.
 <csantander619 gmail.com> wrote:

 What's the correct way of capturing a process output on Windows? I
 found a piece of code on the net, and I tried it, but since I haven't
 worked with pipes before, I don't know what's going on. Anyway, here's
 what I'm trying (using the core32 library):

 //-------------------------------------------
 //code found in
 //http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20682069.html

 void main()
 {
      char [] stdoutname=r"\\.\pipe\my_output_tmp",
          stderrname=r"\\.\pipe\my_error_tmp",
          stdinname=r"\\.\pipe\my_input_tmp";
      Stream fstderr, fstdout, fstdin;
      HANDLE hstderr, hstdout, hstdin;
      HANDLE outstreamhandle, errstreamhandle, instreamhandle;
      char * pOutputFile=toStringz(stdoutname),
 pInputFile=toStringz(stdinname);

      SECURITY_ATTRIBUTES SecAttrs;
      SecAttrs.nLength=SECURITY_ATTRIBUTES.sizeof;
      SecAttrs.bInheritHandle=true;

      outstreamhandle = CreateNamedPipeA(
          pOutputFile,
          PIPE_ACCESS_DUPLEX,
          PIPE_TYPE_BYTE | PIPE_WAIT,
          PIPE_UNLIMITED_INSTANCES,
          8192,
          8192,
          10000,
          &SecAttrs);

      assert(outstreamhandle!=INVALID_HANDLE_VALUE);

      hstdout = CreateFileA(
          pOutputFile,
          GENERIC_READ | GENERIC_WRITE,
          FILE_SHARE_READ | FILE_SHARE_WRITE,
          &SecAttrs,
          CREATE_ALWAYS,
          FILE_ATTRIBUTE_TEMPORARY,
          null );

      assert(hstdout!=INVALID_HANDLE_VALUE);

     instreamhandle= CreateNamedPipeA(
            pInputFile,
          PIPE_ACCESS_DUPLEX,
          PIPE_TYPE_BYTE | PIPE_WAIT,
          PIPE_UNLIMITED_INSTANCES,
          8192,
          8192,
          10000,
          &SecAttrs);

      assert(instreamhandle!=INVALID_HANDLE_VALUE);

      hstdin = CreateFileA(
           pInputFile,
           GENERIC_READ | GENERIC_WRITE,
           FILE_SHARE_READ | FILE_SHARE_WRITE,
           &SecAttrs,
           OPEN_ALWAYS,
           FILE_ATTRIBUTE_TEMPORARY,
           null );

      assert(hstdin!=INVALID_HANDLE_VALUE);

      STARTUPINFOA sui;
      sui.cb          = STARTUPINFOA.sizeof;
      sui.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
      sui.wShowWindow = SW_HIDE;
      sui.hStdOutput  = hstdout;
      sui.hStdInput   = hstdin;

      PROCESS_INFORMATION pi;
      int res = CreateProcessA(null,
          "dir",
          null,
          null,
          true,
          CREATE_NEW_CONSOLE | REALTIME_PRIORITY_CLASS,
          null,
          null,
          &sui,
          &pi);

      DWORD size;
      size = GetFileSize(outstreamhandle, null);
      printf("%d\n", size);
      size = GetFileSize(hstdout, null);
      printf("%d\n", size);
      size = GetFileSize(instreamhandle, null);
      printf("%d\n", size);
      size = GetFileSize(hstdin, null);
      printf("%d\n", size);
      assert (size != INVALID_FILE_SIZE);

      /*
      fstdout=new BufferedFile(new File(cast(std.stream.HANDLE)
 outstreamhandle, FileMode.In | FileMode.Out ));
      foreach(char[] ln;fstdout)
          stdout.writeLine(ln);
      */

      /*
      fstdin=new BufferedFile(new File(cast(std.stream.HANDLE)
 instreamhandle, FileMode.In | FileMode.Out));
      foreach(char[] ln;fstdin)
          stdout.writeLine(ln);
      */
 }
 //-------------------------------------------

 All asserts pass. All sizes return 0. Obviosly, even in an empty
 directory, "dir" outputs something.

 Eventually, I'd like to do what's commented out.

 BTW, I've never worked with pipes before on linux, but I also found
 some code to do the same, and it's unbelievably easy. When/if I get
 this Windows thing sorted out (a couple of days, maybe?) I'll release
 the code for anyone in need of it.
Apr 19 2005
prev sibling next sibling parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
"Regan Heath" <regan netwin.co.nz> wrote in message 
news:opsphdcp0r23k2f5 nrage.netwin.co.nz...
 As promised... Tho it should be noted that you cannot simply run "dir"
 with this. it wants an actual executable not a cmd.exe command like "dir".
 However you can run "cmd /c dir" and get a directory listing.

 It would be nice if Ben had time to look at it and make sure I have not
 abused Stream ;)
Cool stuff. My first thought is that it would be more standard to have Process be a class that has two Stream members (one for the in pipe and one for the out pipe). Something like class Process { InputStream input; OutputStream output; } ... Process proc = new Process("cmd /c dir"); stdout.writefln("%s",proc.input.readLine()); But that's just becuase it feels odd to have Process subclass Stream. But I haven't thought about it too much... See for example Java's Process and PipeStream classes.
Apr 19 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Tue, 19 Apr 2005 19:30:30 -0400, Ben Hinkle <ben.hinkle gmail.com>  
wrote:
 "Regan Heath" <regan netwin.co.nz> wrote in message
 news:opsphdcp0r23k2f5 nrage.netwin.co.nz...
 As promised... Tho it should be noted that you cannot simply run "dir"
 with this. it wants an actual executable not a cmd.exe command like  
 "dir".
 However you can run "cmd /c dir" and get a directory listing.

 It would be nice if Ben had time to look at it and make sure I have not
 abused Stream ;)
Cool stuff. My first thought is that it would be more standard to have Process be a class that has two Stream members (one for the in pipe and one for the out pipe). Something like class Process { InputStream input; OutputStream output; } ... Process proc = new Process("cmd /c dir"); stdout.writefln("%s",proc.input.readLine()); But that's just becuase it feels odd to have Process subclass Stream. But I haven't thought about it too much... See for example Java's Process and PipeStream classes.
Sounds good. I wasn't really sure how it was all supposed to "hang together". So we derive a PipeStream class from Stream. In the PipeStream constructor pass IN or OUT (kinda like how File works). I might give that a go if I find some more time, or if you (or someone else) wants to, feel free. Regan
Apr 19 2005
next sibling parent reply Georg Wrede <georg.wrede nospam.org> writes:
Regan Heath wrote:
 On Tue, 19 Apr 2005 19:30:30 -0400, Ben Hinkle <ben.hinkle gmail.com>
  wrote:
 
 "Regan Heath" <regan netwin.co.nz> wrote in message 
 news:opsphdcp0r23k2f5 nrage.netwin.co.nz...
 
 As promised... Tho it should be noted that you cannot simply run
 "dir" with this. it wants an actual executable not a cmd.exe
 command like "dir". However you can run "cmd /c dir" and get a
 directory listing.
 
 It would be nice if Ben had time to look at it and make sure I
 have not abused Stream ;)
Cool stuff. My first thought is that it would be more standard to have Process be a class that has two Stream members (one for the in pipe and one for the out pipe). Something like class Process { InputStream input; OutputStream output; } ... Process proc = new Process("cmd /c dir"); stdout.writefln("%s",proc.input.readLine());
I hope you put in a stream for stderr, too!
 But that's just becuase it feels odd to have Process subclass
 Stream. But I haven't thought about it too much... See for example
 Java's Process and PipeStream classes.
Sounds good. I wasn't really sure how it was all supposed to "hang together". So we derive a PipeStream class from Stream. In the PipeStream constructor pass IN or OUT (kinda like how File works). I might give that a go if I find some more time, or if you (or someone else) wants to, feel free. Regan
Apr 19 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 20 Apr 2005 09:37:29 +0300, Georg Wrede <georg.wrede nospam.org>  
wrote:
 Regan Heath wrote:
 On Tue, 19 Apr 2005 19:30:30 -0400, Ben Hinkle <ben.hinkle gmail.com>
  wrote:

 "Regan Heath" <regan netwin.co.nz> wrote in message  
 news:opsphdcp0r23k2f5 nrage.netwin.co.nz...

 As promised... Tho it should be noted that you cannot simply run
 "dir" with this. it wants an actual executable not a cmd.exe
 command like "dir". However you can run "cmd /c dir" and get a
 directory listing.
  It would be nice if Ben had time to look at it and make sure I
 have not abused Stream ;)
Cool stuff. My first thought is that it would be more standard to have Process be a class that has two Stream members (one for the in pipe and one for the out pipe). Something like class Process { InputStream input; OutputStream output; } ... Process proc = new Process("cmd /c dir"); stdout.writefln("%s",proc.input.readLine());
I hope you put in a stream for stderr, too!
:) I have actually. I started coding a new version using Ben's idea. Regan
Apr 20 2005
parent "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 20 Apr 2005 22:48:38 +1200, Regan Heath <regan netwin.co.nz> wrote:
 On Wed, 20 Apr 2005 09:37:29 +0300, Georg Wrede <georg.wrede nospam.org>  
 wrote:
 Regan Heath wrote:
 On Tue, 19 Apr 2005 19:30:30 -0400, Ben Hinkle <ben.hinkle gmail.com>
  wrote:

 "Regan Heath" <regan netwin.co.nz> wrote in message  
 news:opsphdcp0r23k2f5 nrage.netwin.co.nz...

 As promised... Tho it should be noted that you cannot simply run
 "dir" with this. it wants an actual executable not a cmd.exe
 command like "dir". However you can run "cmd /c dir" and get a
 directory listing.
  It would be nice if Ben had time to look at it and make sure I
 have not abused Stream ;)
Cool stuff. My first thought is that it would be more standard to have Process be a class that has two Stream members (one for the in pipe and one for the out pipe). Something like class Process { InputStream input; OutputStream output; } ... Process proc = new Process("cmd /c dir"); stdout.writefln("%s",proc.input.readLine());
I hope you put in a stream for stderr, too!
:) I have actually. I started coding a new version using Ben's idea.
And here it is! Thoughts? Regan
Apr 20 2005
prev sibling parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
 So we derive a PipeStream class from Stream. In the PipeStream constructor 
 pass IN or OUT (kinda like how File works). I might give that a go if I 
 find some more time, or if you (or someone else) wants to, feel free.
Sounds reasonable. It might be worth subclassing (or maybe even just reusing) std.stream.File since a pipe is (I think) implemented as file descriptors on the OS's I know about. For example on Windows pipes use ReadFile and WriteFile. I don't know if you were planning on suggesting it to Walter but it might be nice to put the Process class into std.process, too.
Apr 20 2005
parent "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 20 Apr 2005 08:24:42 -0400, Ben Hinkle <ben.hinkle gmail.com>  
wrote:
 So we derive a PipeStream class from Stream. In the PipeStream  
 constructor
 pass IN or OUT (kinda like how File works). I might give that a go if I
 find some more time, or if you (or someone else) wants to, feel free.
Sounds reasonable. It might be worth subclassing (or maybe even just reusing) std.stream.File since a pipe is (I think) implemented as file descriptors on the OS's I know about. For example on Windows pipes use ReadFile and WriteFile.
They do.. if anything I would think that std.stream.File would use PipeStream (see my latest code). The reason I say this is that std.stream.File uses pipes, but also calls CreateFile to create a file on a disk. So it seems to me FileStream extends PipeStream, not the other way round. We would need to move some of the functionality in std.stream.File into PipeStream though i.e. seekability check, seek routine, etc.
 I don't know if you were planning on suggesting it to Walter but it  
 might be nice to put the Process class into std.process, too.
If he thinks it's useful, he's welcome to it. Regan
Apr 20 2005
prev sibling parent reply "Carlos Santander B." <csantander619 gmail.com> writes:
Regan Heath wrote:
 As promised... Tho it should be noted that you cannot simply run "dir"  
 with this. it wants an actual executable not a cmd.exe command like 
 "dir".  However you can run "cmd /c dir" and get a directory listing.
 
 It would be nice if Ben had time to look at it and make sure I have not  
 abused Stream ;)
 
 Regan
 
Great. Thanks. Maybe this should go to Phobos? What do you guys think? -- Carlos Santander Bernal
Apr 19 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Tue, 19 Apr 2005 20:31:17 -0500, Carlos Santander B.  
<csantander619 gmail.com> wrote:
 Regan Heath wrote:
 As promised... Tho it should be noted that you cannot simply run "dir"   
 with this. it wants an actual executable not a cmd.exe command like  
 "dir".  However you can run "cmd /c dir" and get a directory listing.
  It would be nice if Ben had time to look at it and make sure I have  
 not  abused Stream ;)
  Regan
Great. Thanks. Maybe this should go to Phobos? What do you guys think?
It's fine by me :) However, Ben has pointed out a few design changes which I think are a good idea. Regan
Apr 19 2005
parent jicman <jicman_member pathlink.com> writes:
Well, what are you waiting for?  Get at it! :-)

jic

Regan Heath says...
On Tue, 19 Apr 2005 20:31:17 -0500, Carlos Santander B.  
<csantander619 gmail.com> wrote:
 Regan Heath wrote:
 As promised... Tho it should be noted that you cannot simply run "dir"   
 with this. it wants an actual executable not a cmd.exe command like  
 "dir".  However you can run "cmd /c dir" and get a directory listing.
  It would be nice if Ben had time to look at it and make sure I have  
 not  abused Stream ;)
  Regan
Great. Thanks. Maybe this should go to Phobos? What do you guys think?
It's fine by me :) However, Ben has pointed out a few design changes which I think are a good idea. Regan
Apr 20 2005