title: WinAPI - How to redirect all stdout of a program and external DLLs to the Win32 standard output handle?
body: <p>I want to be able to redirect all standard output of a Windows application to the Win32 standard output handle, instead of using a console handle.</p>
  
  <p>For context, the Emacs Win32 FAQ says this:</p>
  
  <blockquote>
    <p>Programs that explicitly use a handle to the console (CON or CON:) instead of stdin and stdout cannot be used as subprocesses to Emacs, and they will also not work in shell-mode [...] There is no convenient way for either Emacs or any shell used in shell-mode to redirect the input and output of such processes from the console to input and output pipes. The only workaround is to use a different implementation of the program that does not use the console directly.
    (<a href="https://www.gnu.org/software/emacs/manual/html_node/efaq-w32/Subprocess-hang.html" rel="nofollow noreferrer">https://www.gnu.org/software/emacs/manual/html_node/efaq-w32/Subprocess-hang.html</a>)</p>
  </blockquote>
  
  <p>I'm experiencing the issue the FAQ describes: when started from Emacs, the program will run but none of its output is displayed in Emacs' <code>shell</code> window until the program exits, as if stdout was buffered and didn't flush while it was running. The same program will output stdout in real-time as expected if run from <code>cmd.exe</code> or ConEmu.</p>
  
  <p>What I want to accomplish is making all the output of the program appear in an Emacs shell so I can jump to a compiler error location as soon as it's printed. I'm willing to rewrite the source of the program to accomplish this. I want to know what "different implementation" details are necessary to accomplish this by using "stdin and stdout" instead of "a handle to the console".</p>
  
  <p>From what I understand:</p>
  
  <ol>
  <li>There are multiple kinds of I/O in Windows, including the C runtime (<code>printf</code>, etc.) and the Win32 layer (<code>ReadFile</code>, etc.).</li>
  <li>I'm assuming "stdin and stdout" refer to <code>STD_INPUT_HANDLE</code> and <code>STD_OUTPUT_HANDLE</code> which can be modified by <code>SetStdHandle()</code>.</li>
  <li>External DLLs loaded by a program will inherit the C runtime <code>stdin</code> and <code>stdout</code> pipes, but this happens on program initialization, before any calls to <code>SetStdHandle()</code> are called, so there is something else you have to do to redirect their output.</li>
  </ol>
  
  <p>I've tried using this code:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;windows.h&gt;
  #include &lt;cstdlib&gt;
  
  int main()
  {
      HANDLE hStdout = CreateFile(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
          NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
      HANDLE hStdin = CreateFile(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
          NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  
      SetStdHandle(STD_OUTPUT_HANDLE, hStdout);
      SetStdHandle(STD_ERROR_HANDLE, hStdout);
      SetStdHandle(STD_INPUT_HANDLE, hStdin);
  
      std::cout &lt;&lt; "Hello, world." &lt;&lt; std::endl;
      printf("Hello, world.\n");
      std::cin.get();
  
      return 0;
  }
  </code></pre>
  
  <p>This has the desired effect, but only on usages of <code>printf</code> and <code>std::cout</code> within the same binary as the redirection code. My program loads an external DLL that uses <code>printf</code> and none of its output is redirected.</p>
  
  <p>Also, I don't want to use <code>AllocConsole()</code> or similar since that opens a separate window, which does not integrate with the parent process (Emacs). What I want is to redirect all stdout so it shows up within the same terminal/console that is running the program instead of a different window (if that makes sense). Since I don't use <code>AllocConsole()</code>, then code like <code>_open_osfhandle((long)hStdout, O_WRONLY|O_TEXT)</code> always returns <code>-1</code> for some reason, so it seems like I can't use <code>dup2()</code> as described <a href="https://stackoverflow.com/a/1695044/5862977">here</a>.</p>
  
  <p><em>See also:</em></p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/54094127/redirecting-stdout-in-win32-does-not-redirect-stdout">Redirecting stdout in win32 does not redirect stdout</a></li>
  <li><a href="https://github.com/emacsorphanage/gnuplot/issues/15" rel="nofollow noreferrer">Can't send buffer to gnuplot under Windows</a></li>
  </ul>