title: Redirecting Input and Output of child process not working
body: <p>I have coded two c++ app, one is console and the other is gui.
  I want the gui app starts the console app and inserts input on it and redirect output and error and show them on the textbox. </p>
  
  <p>my code does not work in gui app after pressing run button and does not show the output and it seems that the gui app freezes !</p>
  
  <p>here is my code :</p>
  
  <p>[console part]:</p>
  
  <pre><code>#include &lt;iostream&gt;
  using namespace std;
  
  int main()
  {
  int pass;
  //cout &lt;&lt; "welcome message from cpp app ..." &lt;&lt; endl;
  cout &lt;&lt; "please enter pass =&gt; ";
  cin &gt;&gt; pass;
  if (pass==12345)
      cout &lt;&lt; "ok!" &lt;&lt; endl;
  else
      cout &lt;&lt; "oops!" &lt;&lt; endl;
  //system("pause");
  return 0;
  }
  </code></pre>
  
  <p>[gui part]:</p>
  
  <pre><code>#include &lt;windows.h&gt;
  #include &lt;CommCtrl.h&gt;
  
  #define TEXTBOX1 100
  #define BUTTON1 101
  
  HWND htbx = nullptr;
  HANDLE hChildStd_IN_Rd = nullptr;
  HANDLE hChildStd_IN_Wr = nullptr;
  HANDLE hChildStd_OUT_Rd = nullptr;
  HANDLE hChildStd_OUT_Wr = nullptr;
  
  int MessageLoop();
  
  void ShowError()
  {
      LPVOID lpMsgBuf;
      DWORD dw = GetLastError();
      DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS;
      FormatMessage(flags, nullptr, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), LPWSTR(&amp;lpMsgBuf), 0, nullptr);
      MessageBox(nullptr, LPCWSTR(lpMsgBuf), L"error", MB_OK);
      LocalFree(lpMsgBuf);
  }
  void WriteToPipe(LPCWSTR Commands2Write) 
  {
      DWORD dwWritten;
      bool bSuccess = false;
      bSuccess = WriteFile(hChildStd_IN_Wr, Commands2Write, sizeof(Commands2Write), &amp;dwWritten, nullptr);
      if (!bSuccess)
          ShowError();
      if (!CloseHandle(hChildStd_IN_Wr))
          ShowError();
  }
  void ReadFromPipe()
  {
      DWORD dwRead;
      LPVOID lpDataBuf[4096];
  
      if (hChildStd_OUT_Rd==INVALID_HANDLE_VALUE)
      {
          MessageBox(0, L"INVALID HANDLE", L"error", MB_OK);
      }
  
      //bool bSuccess = false;
      /*bSuccess = ReadFile(hChildStd_OUT_Rd, lpDataBuf, 4096, &amp;dwRead, nullptr);
      if (!bSuccess)
          ShowError();*/
  
      while (ReadFile(hChildStd_OUT_Rd, lpDataBuf, sizeof(lpDataBuf), &amp;dwRead, nullptr))
      {
         SendMessage(htbx, WM_SETTEXT, 0, LPARAM(LPCWSTR(lpDataBuf)));
        // MessageBox(nullptr, LPCWSTR(lpDataBuf), L"Result", MB_OK);
      }
      LocalFree(lpDataBuf);
  
  }
  void Run()
  {
      bool bSuccess = false;
      PROCESS_INFORMATION PI;
      ZeroMemory(&amp;PI, sizeof(PI));
      STARTUPINFO SI;
      ZeroMemory(&amp;SI, sizeof(SI));
      SI.cb = sizeof(SI);
      SI.dwFlags =  STARTF_USESTDHANDLES;
      //SI.hStdError = hChildStd_OUT_Wr;
      //SI.hStdOutput = hChildStd_OUT_Wr;
      //SI.hStdInput = hChildStd_IN_Rd;
      SI.hStdError = hChildStd_OUT_Rd;
      SI.hStdOutput = hChildStd_OUT_Rd;
      SI.hStdInput = hChildStd_IN_Wr;
  
      SECURITY_ATTRIBUTES SA;
      SA.nLength = sizeof(SECURITY_ATTRIBUTES);
      SA.bInheritHandle = TRUE;
      SA.lpSecurityDescriptor = nullptr;
  
      if (!CreatePipe(&amp;hChildStd_OUT_Rd, &amp;hChildStd_OUT_Wr, &amp;SA, 0))
          ShowError();
      if (!SetHandleInformation(hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0))
          ShowError();
      if (!CreatePipe(&amp;hChildStd_IN_Rd, &amp;hChildStd_IN_Wr, &amp;SA, 0))
          ShowError();
      if (!SetHandleInformation(hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0))
          ShowError();
      bSuccess = CreateProcess(L"C:\\Windows\\system32\\cmd.exe",
          L" /c C:\\testa.exe", nullptr, nullptr, TRUE, 0, nullptr, nullptr, &amp;SI, &amp;PI);
  
      if (!bSuccess){ ShowError(); }
              else{CloseHandle(PI.hProcess);CloseHandle(PI.hThread);}
  
          WriteToPipe(L"12345");
          ReadFromPipe();
  }
  LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  {
  
      switch (Msg)
      {
      case WM_CREATE:
      {
          CreateWindowEx(0, WC_BUTTON, L"Run", WS_VISIBLE | WS_CHILD, 420, 100, 75, 35, hWnd, HMENU(BUTTON1), nullptr, nullptr);
          htbx=CreateWindowEx(0, WC_EDIT, L"", WS_VISIBLE | WS_CHILD | WS_BORDER| ES_MULTILINE, 10, 10, 400, 300, hWnd, HMENU(TEXTBOX1), nullptr, nullptr);
      }
      break;
      case WM_COMMAND:
          {
              switch (LOWORD(wParam))
              {
              case BUTTON1:
                  Run();
                  break;
              default:
                  break;
              }
          }
          break;
      case WM_CLOSE:
          DestroyWindow(hWnd);
          break;
      case WM_DESTROY:
          PostQuitMessage(0);
          break;
      default:
          return DefWindowProc(hWnd, Msg, wParam, lParam);
      }
  
      return 0;
  }
  
  int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreviewInstance, LPSTR lpcmdline, int ncmdshow)
  {
      WNDCLASSEX wndexcls;
      wndexcls.lpszClassName = L"win";
      wndexcls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
      wndexcls.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
      wndexcls.hCursor = LoadCursor(NULL, IDC_ARROW);
      wndexcls.hbrBackground = (HBRUSH)(COLOR_3DSHADOW + 1);
      wndexcls.lpszMenuName = NULL;
      wndexcls.style = NULL;
      wndexcls.hInstance = hInstance;
      wndexcls.cbSize = sizeof(WNDCLASSEX);
      wndexcls.cbClsExtra = 0;
      wndexcls.cbWndExtra = 0;
      wndexcls.lpfnWndProc = WndProc;
      RegisterClassEx(&amp;wndexcls);
      HWND Win_Handle = CreateWindowEx(0, L"win", L"TestApp", WS_OVERLAPPEDWINDOW, 100, 100, 640, 380, 0, 0, hInstance, 0);
      ShowWindow(Win_Handle, SW_SHOWDEFAULT);
      UpdateWindow(Win_Handle);
  
      int exitcode;
      exitcode = MessageLoop();
      return exitcode;
  }
  
  int MessageLoop()
  {
      MSG wnd_msg;
      while (GetMessage(&amp;wnd_msg, NULL, 0, 0)&gt;0)
      {
          TranslateMessage(&amp;wnd_msg);
          DispatchMessage(&amp;wnd_msg);
      }
      return (int)wnd_msg.wParam;
  }
  </code></pre>
  
  <p><b>Update:</b></p>
  
  <p>I have updated the code based on Barmak Shemirani`s answer and used ANSI character set. but the writetopipe part does not work and in the readfrompipe part, if you use "/c dir" as second parameter in CreateProcessA instead of "/c C:\consoleapp.exe" for example, it shows only the first line of output not the total output. why this happen ?</p>
  
  <p><b>[updated code]:</b></p>
  
  <pre><code>#include &lt;windows.h&gt;
  #include &lt;CommCtrl.h&gt;
  
  #define TEXTBOX1 100
  #define BUTTON1 101
  
  HWND htbx = nullptr;
  HANDLE out_read = NULL;
  HANDLE out_write = NULL;
  HANDLE in_read = NULL;
  HANDLE in_write = NULL;
  
  int MessageLoop();
  
  void ShowError()
  {
      LPVOID lpMsgBuf;
      DWORD dw = GetLastError();
      DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS;
      FormatMessageA(flags, nullptr, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), LPSTR(&amp;lpMsgBuf), 0, nullptr);
      MessageBoxA(nullptr, LPCSTR(lpMsgBuf), "error", MB_OK);
      LocalFree(lpMsgBuf);
  }
  
  void WriteToPipe() 
  {
      DWORD writecount;
      char bufw[1024]; 
      //memset(bufw, 12345, 5);
      strncpy_s(bufw, "12345", sizeof(bufw));
  
      if (WriteFile(in_write, bufw, sizeof(bufw), &amp;writecount, NULL))
      {
          if (!writecount)
          {
              ShowError();
          }
  
      }
      if (!CloseHandle(in_write))
          ShowError();
  
      LocalFree(bufw);
  }
  void ReadFromPipe()
  {
      DWORD readCount;
      char bufr[1024];
      memset(bufr, 0, sizeof(bufr));
      if (ReadFile(out_read, bufr, sizeof(bufr), &amp;readCount, NULL))
      {
          if (readCount)
          {
              SendMessageA(htbx, EM_SETSEL, WPARAM(-1), LPARAM(-1));
              SendMessageA(htbx, EM_REPLACESEL, 0, LPARAM(bufr));
          }
      }
      if (!CloseHandle(out_read))
          ShowError();
  
      LocalFree(bufr);
  }
  DWORD WINAPI run(LPVOID)
  {
      PROCESS_INFORMATION pi{};
      STARTUPINFOA si{ sizeof STARTUPINFO };
      si.dwFlags = STARTF_USESTDHANDLES;
  
      { //set handles
  
          SECURITY_ATTRIBUTES secAttr;
          secAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
          secAttr.bInheritHandle = TRUE;
          secAttr.lpSecurityDescriptor = nullptr;
  
          if (!CreatePipe(&amp;out_read, &amp;out_write, &amp;secAttr, 0)) ShowError();
          if (!SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)) ShowError();
          if (!CreatePipe(&amp;in_read, &amp;in_write, &amp;secAttr, 0)) ShowError();
          if (!SetHandleInformation(in_write, HANDLE_FLAG_INHERIT, 0)) ShowError();
  
          si.hStdOutput = out_write;
          si.hStdError = out_write;
          si.hStdInput = in_read;
          si.dwFlags |= STARTF_USESTDHANDLES;
      }
  
      if (!CreateProcessA("C:\\Windows\\system32\\cmd.exe",
          "/c C:\\consoleapp.exe", 0, 0, TRUE, 0, 0, 0, &amp;si, &amp;pi))
          ShowError();
  
      while (pi.hProcess &amp;&amp; WaitForSingleObject(pi.hProcess, 25) == WAIT_TIMEOUT)
      {
          if (out_read == INVALID_HANDLE_VALUE)
              ShowError();
          if (in_write == INVALID_HANDLE_VALUE)
              ShowError();
  
          WriteToPipe();
          ReadFromPipe();
      }
  
      CloseHandle(pi.hProcess);
      CloseHandle(pi.hThread);
  
      return 0;
  }
  
  LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  {
      switch (Msg)
      {
      case WM_CREATE:
      {
          CreateWindowExA(0, WC_BUTTONA, "Run", WS_VISIBLE | WS_CHILD, 420, 100, 75, 35, hWnd, HMENU(BUTTON1), nullptr, nullptr);
          htbx=CreateWindowExA(0, WC_EDITA, "", WS_VISIBLE | WS_CHILD | WS_BORDER| ES_MULTILINE, 10, 10, 400, 300, hWnd, HMENU(TEXTBOX1), nullptr, nullptr);
      }
      break;
      case WM_COMMAND:
          {
              switch (LOWORD(wParam))
              {
              case BUTTON1:
                  //Run();
                  CreateThread(NULL, 0, run, 0, 0, NULL);
                  break;
              default:
                  break;
              }
          }
          break;
      case WM_CLOSE:
          DestroyWindow(hWnd);
          break;
      case WM_DESTROY:
          PostQuitMessage(0);
          break;
      default:
          return DefWindowProc(hWnd, Msg, wParam, lParam);
      }
      return 0;
  }
  
  int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreviewInstance, LPSTR lpcmdline, int ncmdshow)
  {
      WNDCLASSEXA wndexcls;
      wndexcls.lpszClassName = "win";
      wndexcls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
      wndexcls.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
      wndexcls.hCursor = LoadCursor(NULL, IDC_ARROW);
      wndexcls.hbrBackground = (HBRUSH)(COLOR_3DSHADOW + 1);
      wndexcls.lpszMenuName = NULL;
      wndexcls.style = NULL;
      wndexcls.hInstance = hInstance;
      wndexcls.cbSize = sizeof(WNDCLASSEX);
      wndexcls.cbClsExtra = 0;
      wndexcls.cbWndExtra = 0;
      wndexcls.lpfnWndProc = WndProc;
      RegisterClassExA(&amp;wndexcls);
      HWND Win_Handle = CreateWindowExA(0, "win", "TestApp", WS_OVERLAPPEDWINDOW, 100, 100, 640, 380, 0, 0, hInstance, 0);
      ShowWindow(Win_Handle, SW_SHOWDEFAULT);
      UpdateWindow(Win_Handle);
      int exitcode;
      exitcode = MessageLoop();
      return exitcode;
  }
  
  int MessageLoop()
  {
      MSG wnd_msg;
      while (GetMessage(&amp;wnd_msg, NULL, 0, 0)&gt;0)
      {
          TranslateMessage(&amp;wnd_msg);
          DispatchMessage(&amp;wnd_msg);
      }
      return (int)wnd_msg.wParam;
  }
  </code></pre>