Child process and pipes

Child process and pipes

Post by VK Hanso » Sat, 15 Mar 2003 05:49:37



I am writing a gui program on XP.  I need to have it start a command console to execute a command and read the output of the command for display in a window.  I used CreateProcess to run "cmd.exe /c <command>".  I am limiting <command> to be only commands processed by the xp command interpreter, it will not execute programs.

I am trying the approach of redirecting the STDOUT pipe and reading from it.  I do not know how to distinguish between the cmd.exe stdout and the actual commands' stdout.  

If I use CREATE_NEW_CONSOLE with CreateProcess do I need to have the process start cmd.exe?  Could I then just execute the command directly?

I read the SDK on creating child processes and redirecting output but I do not understand the code.  I read here (from last year) that STDIN and STDOUT from a console process are not available directly to a GUI program, but I'm lost as to how to set this up.

Any help would be appreciated!  TIA

--
Victor K. Hanson
Windows 2000 MCSE, MCSA
MCP ID# 2781112

 
 
 

Child process and pipes

Post by Gary Chanso » Sat, 15 Mar 2003 06:47:14



Quote:> I am writing a gui program on XP.  I need to have it start a command
> console to execute a command and read the output of the command
> for display in a window.  I used CreateProcess to run "cmd.exe /c
> <command>".  I am limiting <command> to be only commands
> processed by the xp command interpreter, it will not execute programs.

> I am trying the approach of redirecting the STDOUT pipe and reading
> from it.  I do not know how to distinguish between the cmd.exe stdout
> and the actual commands' stdout.

> If I use CREATE_NEW_CONSOLE with CreateProcess do I need to
> have the process start cmd.exe?  Could I then just execute the command
> directly?

> I read the SDK on creating child processes and redirecting output but I do
> not understand the code.  I read here (from last year) that STDIN and
> STDOUT from a console process are not available directly to a GUI program,
> but I'm lost as to how to set this up.

> Any help would be appreciated!  TIA

    After reading your message twice, I'm still not sure what you're asking.

    You can not distinguish between the STDOUT from CMD.EXE and from an
application.  They're both just characters sent to the same file handle.

    If you are launching a program from a GUI app, CREATE_NEW_CONSOLE will not
make any difference because a new console has to be created anyway.

    It is true that a GUI app does not have direct access to STD I/O (at least
without special effort), but that's irrelevant to what I think you're trying
to do (ie sending the output of a console program to your program).

    How far did you get at implementing redirection?  Can you post specific
questions or code samples?

--

-Gary Chanson (MS MVP for Windows SDK)
-Software Consultant (Embedded systems and Real Time Controls)

-War is the last resort of the incompetent.

 
 
 

Child process and pipes

Post by VK Hanso » Sat, 15 Mar 2003 07:46:16


Sorry about that.  I have not gotten far with the redirection at all.

What I am trying to do is this: In a window i type "dir".  I prepend
"cmd.exe /c" to it so it looks like "cmd.exe /c dir".  What I'd like to do
is somehow redirect the output of that command to a buffer for display back
in the window. In this case I'd get something like

 Volume in drive D is Data
 Volume Serial Number is 58A7-D8CC

 Directory of D:\

02/22/2003  02:09 PM    <DIR>          Media
02/22/2003  02:17 PM    <DIR>          Microsoft Visual Studio .NET
02/22/2003  02:17 PM    <DIR>          NeverwinterNights
03/05/2003  06:20 AM    <DIR>          Visual Studio Projects
02/23/2003  05:49 PM    <DIR>          WUTemp
               1 File(s)      4,425,856 bytes
               5 Dir(s)  35,657,478,144 bytes free

How do I access the output of the command?  I am assuming that a cmd.exe
session also has stdin, stdout, stderr pipes associated with it.  This is
what I've done so far:

//***BEG***
ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);
bFuncRetn = CreateProcess(NULL, TEXT ("cmd.exe"),
                            NULL, NULL,         // don't care about security
attrs yet
                            TRUE,                    // handles are
inherited
                            CREATE_NEW_CONSOLE,
                            GetEnvironmentStrings(), "D:\", // current
working dir
                            &siStartInfo, &piProcInfo);

DuplicateHandle (piProcInfo.hProcess, GetStdHandle (STD_OUTPUT_HANDLE),
GetCurrentProcess(), &hStdOUT, 0, FALSE, DUPLICATE_SAME_ACCESS);

ReadFile (hStdOUT, cBuf, 1024, &dwBytesRead, NULL);
// ***END***

I purposely omitted all the error checking.  Using GetLastError (and
FormatMessage) the error from ReadFile is "Invalid File Handle".

This is as far as I've gotten.  I have no idea if I'm on the right track or
way off the deep end :).  Thank you for your response, Gary.

--
Victor K. Hanson
Windows 2000 MCSE, MCSA
MCP ID# 2781112

 
 
 

Child process and pipes

Post by VK Hanso » Sat, 15 Mar 2003 07:48:39


Whooops... the second param in CreateProcess should look like TEXT ("cmd.exe /c dir")

--
Victor K. Hanson
Windows 2000 MCSE, MCSA
MCP ID# 2781112


  Sorry about that.  I have not gotten far with the redirection at all.

  What I am trying to do is this: In a window i type "dir".  I prepend
  "cmd.exe /c" to it so it looks like "cmd.exe /c dir".  What I'd like to do
  is somehow redirect the output of that command to a buffer for display back
  in the window. In this case I'd get something like

   Volume in drive D is Data
   Volume Serial Number is 58A7-D8CC

   Directory of D:\

  02/22/2003  02:09 PM    <DIR>          Media
  02/22/2003  02:17 PM    <DIR>          Microsoft Visual Studio .NET
  02/22/2003  02:17 PM    <DIR>          NeverwinterNights
  03/05/2003  06:20 AM    <DIR>          Visual Studio Projects
  02/23/2003  05:49 PM    <DIR>          WUTemp
                 1 File(s)      4,425,856 bytes
                 5 Dir(s)  35,657,478,144 bytes free

  How do I access the output of the command?  I am assuming that a cmd.exe
  session also has stdin, stdout, stderr pipes associated with it.  This is
  what I've done so far:

  //***BEG***
  ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
  ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
  siStartInfo.cb = sizeof(STARTUPINFO);
  bFuncRetn = CreateProcess(NULL, TEXT ("cmd.exe"),
                              NULL, NULL,         // don't care about security
  attrs yet
                              TRUE,                    // handles are
  inherited
                              CREATE_NEW_CONSOLE,
                              GetEnvironmentStrings(), "D:\", // current
  working dir
                              &siStartInfo, &piProcInfo);

  DuplicateHandle (piProcInfo.hProcess, GetStdHandle (STD_OUTPUT_HANDLE),
  GetCurrentProcess(), &hStdOUT, 0, FALSE, DUPLICATE_SAME_ACCESS);

  ReadFile (hStdOUT, cBuf, 1024, &dwBytesRead, NULL);
  // ***END***

  I purposely omitted all the error checking.  Using GetLastError (and
  FormatMessage) the error from ReadFile is "Invalid File Handle".

  This is as far as I've gotten.  I have no idea if I'm on the right track or
  way off the deep end :).  Thank you for your response, Gary.

  --
  Victor K. Hanson
  Windows 2000 MCSE, MCSA
  MCP ID# 2781112

 
 
 

Child process and pipes

Post by Carey Gregor » Sat, 15 Mar 2003 08:26:08



>bFuncRetn = CreateProcess(NULL, TEXT ("cmd.exe"),
>                            NULL, NULL,         // don't care about security
>attrs yet
>                            TRUE,                    // handles are
>inherited
>                            CREATE_NEW_CONSOLE,
>                            GetEnvironmentStrings(), "D:\", // current
>working dir
>                            &siStartInfo, &piProcInfo);

>DuplicateHandle (piProcInfo.hProcess, GetStdHandle (STD_OUTPUT_HANDLE),
>GetCurrentProcess(), &hStdOUT, 0, FALSE, DUPLICATE_SAME_ACCESS);

>ReadFile (hStdOUT, cBuf, 1024, &dwBytesRead, NULL);

This isn't going to work.  CMD.EXE has probably already finished by the time
you execute DuplicateHandle.   What you need to do is create the pipe,
associate it with stdout, and then execute the child process.  I wrote the
following code for a technical article in "OS/2 Professional" magazine back
in 1994, so you'll have to change the API calls to Win32, but the logic is
about the same under Windows.

   // create two unnamed pipes

   DosCreatePipe(&hRead1, &hWrite1, 0);
   DosCreatePipe(&hRead2, &hWrite2, 0);

   // redirect stdin and stdout to the pipes

   hChildStdIn = 0;
   hChildStdOut = 1;
   DosDupHandle(hRead1, &hChildStdIn);
   DosDupHandle(hWrite2, &hChildStdOut);

   // start the child program - it will inherit our stdin/stdout which
   // is currently the two pipes created above

   DosExecPgm(FailName, sizeof(FailName), EXEC_ASYNC, NULL, NULL,
               &Results, "child.exe");

   // restore our stdin/stdout - this does not affect the child

   DosDupHandle(hStdIn, &hChildStdIn);
   DosDupHandle(hStdOut, &hChildStdOut);

   // write to the pipe - the child process will receive this as
   // input on stdin

   DosWrite(hWrite1, "hello", strlen("hello"), &WriteLen);

   // read the pipe - this will be whatever the child writes to stdout

   DosRead(hRead2, Buffer, sizeof(Buffer), &ReadLen);

--
Carey Gregory
Windows Print Drivers & Components
http://www.gw-tech.com

 
 
 

Child process and pipes

Post by Garrett Youn » Sat, 15 Mar 2003 09:20:07


some commands (internal and external) also write to stderr...

hChildStdErr = 2;

you can also dup this one to hRead2 so you can read stdout and stderr from the same pipe.



> >bFuncRetn = CreateProcess(NULL, TEXT ("cmd.exe"),
> >                            NULL, NULL,         // don't care about security
> >attrs yet
> >                            TRUE,                    // handles are
> >inherited
> >                            CREATE_NEW_CONSOLE,
> >                            GetEnvironmentStrings(), "D:\", // current
> >working dir
> >                            &siStartInfo, &piProcInfo);

> >DuplicateHandle (piProcInfo.hProcess, GetStdHandle (STD_OUTPUT_HANDLE),
> >GetCurrentProcess(), &hStdOUT, 0, FALSE, DUPLICATE_SAME_ACCESS);

> >ReadFile (hStdOUT, cBuf, 1024, &dwBytesRead, NULL);

> This isn't going to work.  CMD.EXE has probably already finished by the time
> you execute DuplicateHandle.   What you need to do is create the pipe,
> associate it with stdout, and then execute the child process.  I wrote the
> following code for a technical article in "OS/2 Professional" magazine back
> in 1994, so you'll have to change the API calls to Win32, but the logic is
> about the same under Windows.

>    // create two unnamed pipes

>    DosCreatePipe(&hRead1, &hWrite1, 0);
>    DosCreatePipe(&hRead2, &hWrite2, 0);

>    // redirect stdin and stdout to the pipes

>    hChildStdIn = 0;
>    hChildStdOut = 1;
>    DosDupHandle(hRead1, &hChildStdIn);
>    DosDupHandle(hWrite2, &hChildStdOut);

>    // start the child program - it will inherit our stdin/stdout which
>    // is currently the two pipes created above

>    DosExecPgm(FailName, sizeof(FailName), EXEC_ASYNC, NULL, NULL,
>                &Results, "child.exe");

>    // restore our stdin/stdout - this does not affect the child

>    DosDupHandle(hStdIn, &hChildStdIn);
>    DosDupHandle(hStdOut, &hChildStdOut);

>    // write to the pipe - the child process will receive this as
>    // input on stdin

>    DosWrite(hWrite1, "hello", strlen("hello"), &WriteLen);

>    // read the pipe - this will be whatever the child writes to stdout

>    DosRead(hRead2, Buffer, sizeof(Buffer), &ReadLen);

> --
> Carey Gregory
> Windows Print Drivers & Components
> http://www.gw-tech.com

 
 
 

Child process and pipes

Post by VK Hanso » Sat, 15 Mar 2003 10:37:52


Ok, I understand the logic of creating the pipe beforehand.   I will definitely give this a try :), though I've been told that the stdin/stdout/stderr is going to be different for console programs than it is in a windows program.

So the problem here is how does a windows program gain access to the stdout/stderr of a console program?

To Be Continued....

--
Victor K. Hanson
Windows 2000 MCSE, MCSA
MCP ID# 2781112



  >bFuncRetn = CreateProcess(NULL, TEXT ("cmd.exe"),
  >                            NULL, NULL,         // don't care about security
  >attrs yet
  >                            TRUE,                    // handles are
  >inherited
  >                            CREATE_NEW_CONSOLE,
  >                            GetEnvironmentStrings(), "D:\", // current
  >working dir
  >                            &siStartInfo, &piProcInfo);
  >
  >DuplicateHandle (piProcInfo.hProcess, GetStdHandle (STD_OUTPUT_HANDLE),
  >GetCurrentProcess(), &hStdOUT, 0, FALSE, DUPLICATE_SAME_ACCESS);
  >
  >ReadFile (hStdOUT, cBuf, 1024, &dwBytesRead, NULL);

  This isn't going to work.  CMD.EXE has probably already finished by the time
  you execute DuplicateHandle.   What you need to do is create the pipe,
  associate it with stdout, and then execute the child process.  I wrote the
  following code for a technical article in "OS/2 Professional" magazine back
  in 1994, so you'll have to change the API calls to Win32, but the logic is
  about the same under Windows.

     // create two unnamed pipes

     DosCreatePipe(&hRead1, &hWrite1, 0);
     DosCreatePipe(&hRead2, &hWrite2, 0);

     // redirect stdin and stdout to the pipes

     hChildStdIn = 0;
     hChildStdOut = 1;
     DosDupHandle(hRead1, &hChildStdIn);
     DosDupHandle(hWrite2, &hChildStdOut);

     // start the child program - it will inherit our stdin/stdout which
     // is currently the two pipes created above

     DosExecPgm(FailName, sizeof(FailName), EXEC_ASYNC, NULL, NULL,
                 &Results, "child.exe");

     // restore our stdin/stdout - this does not affect the child

     DosDupHandle(hStdIn, &hChildStdIn);
     DosDupHandle(hStdOut, &hChildStdOut);

     // write to the pipe - the child process will receive this as
     // input on stdin

     DosWrite(hWrite1, "hello", strlen("hello"), &WriteLen);

     // read the pipe - this will be whatever the child writes to stdout

     DosRead(hRead2, Buffer, sizeof(Buffer), &ReadLen);

  --
  Carey Gregory
  Windows Print Drivers & Components
  http://www.gw-tech.com

 
 
 

Child process and pipes

Post by Carey Gregor » Sat, 15 Mar 2003 11:13:25



>Ok, I understand the logic of creating the pipe beforehand.   I will definitely give this a try :), though I've been told that the stdin/stdout/stderr is going to be different for console programs than it is in a windows program.

>So the problem here is how does a windows program gain access to the stdout/stderr of a console program?

>To Be Continued....

Sorry, forgot that "little" detail....

AllocConsole();
freopen("conin$", "r", stdin);
freopen("conout$", "w", stdout);
freopen("conout$", "w", stderr);

--
Carey Gregory
Windows Print Drivers & Components
http://www.gw-tech.com

 
 
 

Child process and pipes

Post by VK Hanso » Sun, 16 Mar 2003 08:25:24


I want to say thanks to the guys who responded!  The issue is resolved, here's the resulting code to help others who run into this:

ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);
sa.nLength = sizeof (SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
if (!AllocConsole ())
{
LastError();
break;

Quote:}

hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
// set a write handle to the pipe to be stdout
if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
{
LastError();
break;
Quote:}

// Create a noninheritable read handle to the pipe and close the
// inheritable read handle
if (!DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
GetCurrentProcess(), &hChildStdoutRdDup , 0,
FALSE,
DUPLICATE_SAME_ACCESS))
{
LastError();
break;
Quote:}

// create the pipe for child's stdout
if (!CreatePipe (&hChildStdoutRd, &hChildStdoutWr, &sa, 0))
{
LastError();
break;
Quote:}

CloseHandle(hChildStdoutRd);
// Create the child process
bFuncRet = CreateProcess (NULL, "cmd.exe /c dir", NULL, NULL,
TRUE, 0, GetEnvironmentStrings (), "d:\\",
&siStartInfo, &piProcInfo);
if (!bFuncRet)
{
LastError();
break;
Quote:}

// Restore saved stdout
if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))
{
LastError();
break;
Quote:}

// Read from the redirected stdout
if (!ReadFile (hChildStdoutRdDup, chbuf, dwBytes, &dwRead, NULL))
{
CloseHandle(hChildStdoutRdDup);
LastError ();
break;
Quote:}

CloseHandle (hChildStdoutRdDup);
CloseHandle (hChildStdoutWr);

// chbuf now holds the result of the command

--
Victor K. Hanson
Windows 2000 MCSE, MCSA
MCP ID# 2781112


  I am writing a gui program on XP.  I need to have it start a command console to execute a command and read the output of the command for display in a window.  I used CreateProcess to run "cmd.exe /c <command>".  I am limiting <command> to be only commands processed by the xp command interpreter, it will not execute programs.

  I am trying the approach of redirecting the STDOUT pipe and reading from it.  I do not know how to distinguish between the cmd.exe stdout and the actual commands' stdout.  

  If I use CREATE_NEW_CONSOLE with CreateProcess do I need to have the process start cmd.exe?  Could I then just execute the command directly?

  I read the SDK on creating child processes and redirecting output but I do not understand the code.  I read here (from last year) that STDIN and STDOUT from a console process are not available directly to a GUI program, but I'm lost as to how to set this up.

  Any help would be appreciated!  TIA

  --
  Victor K. Hanson
  Windows 2000 MCSE, MCSA
  MCP ID# 2781112

 
 
 

Child process and pipes

Post by VK Hanso » Sun, 16 Mar 2003 11:48:53


Please ignore the previous post!!! I have no idea how this code got twisted around!!!  This is the REAL VERSION!

One note: the ReadFile below only reads one line from the output, so there are bugs.  But the pipe redirection seems to work fine now.

--
Victor K. Hanson
Windows 2000 MCSE, MCSA
MCP ID# 2781112


  I want to say thanks to the guys who responded!  The issue is resolved, here's the resulting code to help others who run into this:

  ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
  ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
  siStartInfo.cb = sizeof(STARTUPINFO);
  sa.nLength = sizeof (SECURITY_ATTRIBUTES);
  sa.bInheritHandle = TRUE;
  sa.lpSecurityDescriptor = NULL;
  if (!AllocConsole ())
  {
  LastError();
  break;
  }
  // save the original stdout handle associated with the console
  hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
  // create the pipe for child's stdout
  if (!CreatePipe (&hChildStdoutRd, &hChildStdoutWr, &sa, 0))
  {
  LastError();
  break;
  }
  // set a write handle to the pipe to be stdout
  if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
  {
  LastError();
  break;
  }
  // Create a noninheritable read handle to the pipe and close the
  // inheritable read handle
  if (!DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
  GetCurrentProcess(), &hChildStdoutRdDup , 0,
  FALSE,
  DUPLICATE_SAME_ACCESS))
  {
  LastError();
  break;
  }
  CloseHandle(hChildStdoutRd);
  // Create the child process
  bFuncRet = CreateProcess (NULL, "cmd.exe /c dir", NULL, NULL,
  TRUE, 0, GetEnvironmentStrings (), "d:\\",
  &siStartInfo, &piProcInfo);
  if (!bFuncRet)
  {
  LastError();
  break;
  }
  // Restore saved stdout
  if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))
  {
  LastError();
  break;
  }
  // Read from the redirected stdout
  if (!ReadFile (hChildStdoutRdDup, chbuf, dwBytes, &dwRead, NULL))
  {
  CloseHandle(hChildStdoutRdDup);
  LastError ();
  break;
  }
  CloseHandle (hChildStdoutRdDup);
  CloseHandle (hChildStdoutWr);

  // chbuf now holds the result of the command

  --
  Victor K. Hanson
  Windows 2000 MCSE, MCSA
  MCP ID# 2781112


    I am writing a gui program on XP.  I need to have it start a command console to execute a command and read the output of the command for display in a window.  I used CreateProcess to run "cmd.exe /c <command>".  I am limiting <command> to be only commands processed by the xp command interpreter, it will not execute programs.

    I am trying the approach of redirecting the STDOUT pipe and reading from it.  I do not know how to distinguish between the cmd.exe stdout and the actual commands' stdout.  

    If I use CREATE_NEW_CONSOLE with CreateProcess do I need to have the process start cmd.exe?  Could I then just execute the command directly?

    I read the SDK on creating child processes and redirecting output but I do not understand the code.  I read here (from last year) that STDIN and STDOUT from a console process are not available directly to a GUI program, but I'm lost as to how to set this up.

    Any help would be appreciated!  TIA

    --
    Victor K. Hanson
    Windows 2000 MCSE, MCSA
    MCP ID# 2781112

 
 
 

Child process and pipes

Post by VK Hanso » Sun, 16 Mar 2003 13:34:15


Okay, learning bit by bit now :).  ReadFile was reading exactly the length that I was telling it to, not just one line (which doesn't really make sense).  The buffer was being displayed in an edit window that I had not set to multiline :).  DOH!  
Also, I needed to test for the exit status of the process, I was displaying the buffer before the process was finished and getting only some of what was expected.  What's nice is that it lead me to discover the nice PeekNamedPipe function which can tell me how many bytes are sitting in the buffer.  Now I can dynamically allocate the display buffer.

Thanks again to those who helped :)

--
Victor K. Hanson
Windows 2000 MCSE, MCSA
MCP ID# 2781112


  Please ignore the previous post!!! I have no idea how this code got twisted around!!!  This is the REAL VERSION!

  One note: the ReadFile below only reads one line from the output, so there are bugs.  But the pipe redirection seems to work fine now.

  --
  Victor K. Hanson
  Windows 2000 MCSE, MCSA
  MCP ID# 2781112


    I want to say thanks to the guys who responded!  The issue is resolved, here's the resulting code to help others who run into this:

    ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
    ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
    siStartInfo.cb = sizeof(STARTUPINFO);
    sa.nLength = sizeof (SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;
    if (!AllocConsole ())
    {
    LastError();
    break;
    }
    // save the original stdout handle associated with the console
    hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    // create the pipe for child's stdout
    if (!CreatePipe (&hChildStdoutRd, &hChildStdoutWr, &sa, 0))
    {
    LastError();
    break;
    }
    // set a write handle to the pipe to be stdout
    if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
    {
    LastError();
    break;
    }
    // Create a noninheritable read handle to the pipe and close the
    // inheritable read handle
    if (!DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
    GetCurrentProcess(), &hChildStdoutRdDup , 0,
    FALSE,
    DUPLICATE_SAME_ACCESS))
    {
    LastError();
    break;
    }
    CloseHandle(hChildStdoutRd);
    // Create the child process
    bFuncRet = CreateProcess (NULL, "cmd.exe /c dir", NULL, NULL,
    TRUE, 0, GetEnvironmentStrings (), "d:\\",
    &siStartInfo, &piProcInfo);
    if (!bFuncRet)
    {
    LastError();
    break;
    }
    // Restore saved stdout
    if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))
    {
    LastError();
    break;
    }
    // Read from the redirected stdout
    if (!ReadFile (hChildStdoutRdDup, chbuf, dwBytes, &dwRead, NULL))
    {
    CloseHandle(hChildStdoutRdDup);
    LastError ();
    break;
    }
    CloseHandle (hChildStdoutRdDup);
    CloseHandle (hChildStdoutWr);

    // chbuf now holds the result of the command

    --
    Victor K. Hanson
    Windows 2000 MCSE, MCSA
    MCP ID# 2781112


      I am writing a gui program on XP.  I need to have it start a command console to execute a command and read the output of the command for display in a window.  I used CreateProcess to run "cmd.exe /c <command>".  I am limiting <command> to be only commands processed by the xp command interpreter, it will not execute programs.

      I am trying the approach of redirecting the STDOUT pipe and reading from it.  I do not know how to distinguish between the cmd.exe stdout and the actual commands' stdout.  

      If I use CREATE_NEW_CONSOLE with CreateProcess do I need to have the process start cmd.exe?  Could I then just execute the command directly?

      I read the SDK on creating child processes and redirecting output but I do not understand the code.  I read here (from last year) that STDIN and STDOUT from a console process are not available directly to a GUI program, but I'm lost as to how to set this up.

      Any help would be appreciated!  TIA

      --
      Victor K. Hanson
      Windows 2000 MCSE, MCSA
      MCP ID# 2781112

 
 
 

1. Parent / child process communication with pipes

Hi all !

I try to implement a parent <-> child communication
using anonymous pipes.

I want the parent to write into the child's standard
input stream and read from its standard output stream.

+----------------+       +----------------+
| Parent         | pipe1 |          Child |
|       write -> |=======| stdin ->       |
|       read  <- |=======| stdout <-      |
|                | pipe2 |                |
+----------------+       +----------------+

In the parent, I use CreateProcess(), CreatePipe()
and CloseHandle() for unused handles.

My problem is the following :

When the parent process stops (due to a crash or
even a normal termination), the child process is
not killed automatically.

On UNIX systems, the child process gets a SIGPIPE
signal and can manage to stop properly.

Is there any way to handle this on Windows systems ?

Which native communication method would you use to
implement this ?
Remark: We need to find a solution near the UNIX
pipe method because we have to provide a solution
on both platforms !

Thanks.
Seb.

2. why is it rebooting

3. Using anonymous pipe between service and child process

4. Files renamed on import

5. Q: Using anon. pipes for communication w/ child process

6. 16Mhz 68881

7. Q: Usage of anon. pipes for communication w/ child process

8. Win 2000 and audio CDs

9. child process and child thread

10. URGENT limitted number of processes or child processes?

11. How to kill child processes spawned by a process?

12. process tree/hierarchy (parent/child process relationship) in Windows NT

13. Process ID and parent/child processes