title: How to read output from cmd.exe using CreateProcess() and CreatePipe()
body: <blockquote>
    <p>How to read output from cmd.exe using CreateProcess() and CreatePipe()   </p>
  </blockquote>
  
  <p>I have been trying to create a child process executing <code>cmd.exe</code> with a command-line designating <code>/K dir</code>. The purpose is to read the output from the command back into the parent process using pipes. </p>
  
  <p>I've already got <code>CreateProcess()</code> working, however the step involving pipes are causing me trouble. Using pipes, the new console window is not displaying (like it was before), and the parent process is stuck in the call to <code>ReadFile()</code>.</p>
  
  <p>Does anyone have an idea of what I'm doing wrong?</p>
  
  <pre><code>#include &lt;Windows.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;tchar.h&gt;
  
  #define BUFFSZ 4096
  
  HANDLE g_hChildStd_IN_Rd = NULL;
  HANDLE g_hChildStd_IN_Wr = NULL;
  HANDLE g_hChildStd_OUT_Rd = NULL;
  HANDLE g_hChildStd_OUT_Wr = NULL;
  
  int wmain(int argc, wchar_t* argv[]) 
  {
      int result;
      wchar_t aCmd[BUFFSZ] = TEXT("/K dir"); // CMD /?
      STARTUPINFO si;
      PROCESS_INFORMATION pi;
      SECURITY_ATTRIBUTES sa;
  
      printf("Starting...\n");
  
      ZeroMemory(&amp;si, sizeof(STARTUPINFO));
      ZeroMemory(&amp;pi, sizeof(PROCESS_INFORMATION));
      ZeroMemory(&amp;sa, sizeof(SECURITY_ATTRIBUTES));
  
      // Create one-way pipe for child process STDOUT
      if (!CreatePipe(&amp;g_hChildStd_OUT_Rd, &amp;g_hChildStd_OUT_Wr, &amp;sa, 0)) {
          printf("CreatePipe() error: %ld\n", GetLastError());
      }
  
      // Ensure read handle to pipe for STDOUT is not inherited
      if (!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) {
          printf("SetHandleInformation() error: %ld\n", GetLastError());
      }
  
      // Create one-way pipe for child process STDIN
      if (!CreatePipe(&amp;g_hChildStd_IN_Rd, &amp;g_hChildStd_IN_Wr, &amp;sa, 0)) {
          printf("CreatePipe() error: %ld\n", GetLastError());
      }
  
      // Ensure write handle to pipe for STDIN is not inherited
      if (!SetHandleInformation(g_hChildStd_IN_Rd, HANDLE_FLAG_INHERIT, 0)) {
          printf("SetHandleInformation() error: %ld\n", GetLastError());
      }
  
      si.cb = sizeof(STARTUPINFO);
      si.hStdError = g_hChildStd_OUT_Wr;
      si.hStdOutput = g_hChildStd_OUT_Wr;
      si.hStdInput = g_hChildStd_IN_Rd;
      si.dwFlags |= STARTF_USESTDHANDLES;
  
      sa.nLength = sizeof(SECURITY_ATTRIBUTES);
      sa.lpSecurityDescriptor = NULL;
      // Pipe handles are inherited
      sa.bInheritHandle = true;
  
      // Creates a child process
      result = CreateProcess(
          TEXT("C:\\Windows\\System32\\cmd.exe"),     // Module
          aCmd,                                       // Command-line
          NULL,                                       // Process security attributes
          NULL,                                       // Primary thread security attributes
          true,                                       // Handles are inherited
          CREATE_NEW_CONSOLE,                         // Creation flags
          NULL,                                       // Environment (use parent)
          NULL,                                       // Current directory (use parent)
          &amp;si,                                        // STARTUPINFO pointer
          &amp;pi                                         // PROCESS_INFORMATION pointer
          );
  
      if (result) {
          printf("Child process has been created...\n");
      }
      else {
          printf("Child process could not be created\n");
      }
  
      bool bStatus;
      CHAR aBuf[BUFFSZ + 1];
      DWORD dwRead;
      DWORD dwWrite;
      // GetStdHandle(STD_OUTPUT_HANDLE)
  
      while (true) {
          bStatus = ReadFile(g_hChildStd_OUT_Rd, aBuf, sizeof(aBuf), &amp;dwRead, NULL);
          if (!bStatus || dwRead == 0) {
              break;
          }
          aBuf[dwRead] = '\0';
          printf("%s\n", aBuf);
      }
  
          // Wait until child process exits
          WaitForSingleObject(pi.hProcess, INFINITE);
  
          // Close process and thread handles
          CloseHandle(pi.hProcess);
          CloseHandle(pi.hThread);
  
          printf("Stopping...\n");
  
          return 0;
      }
  </code></pre>