December 4th, 2025
like1 reaction

How can I read the standard output of an already-running process?

A customer wanted to know if they could read the standard output of an already-running process. They didn’t explain why, but my guess is that their main process launches a helper process (not written by them) to begin some workflow, and eventually that helper process launches a console process, which produces the desired output. But they want their main process to read that output, presumably so they can continue automating the workflow.

Unfortunately, there is no way to read the standard output of an already-running process. Standard handles, like the environment variables and current directory, are properties of the process that are not exposed to outsiders by the system.¹

In particular, programs do not expect these properties to change asynchronously. For example, a program that might check the standard output handle and put up a progress spinner if it is a console but not if it is a pipe or file.

Some programs check whether their standard output handle refers to a console (in which case they will use functions like WriteConsoleW to get Unicode support or Set­Console­Text­Attribute to get colors. Furthermore, the C runtime libraries typically check their standard output handle at startup to see whether it has been redirected to a file. This alters the behavior of standard I/O functions because buffering is enabled for non-interactive standard output. If you could change the standard output handle out from under a program’s nose, it would try using Write­ConsoleW to write to something that isn’t a console any more. The calls would fail, and the program would generate no output at all.

It’s actually worse because it’s not uncommon for programs to call Get­Std­Handle and save the value in a variable, then use that variable to write to standard output instead of calling Get­Std­Handle every time. So even if you managed to change the standard output handle, you’d be too late.

What you have to do is find a way to influence the standard output of the console process at the point it is created. Since the presumed intention is for the output of the child process to be visible to the user, the console process probably inherits its standard output from its parent, so you can get the child to operate with redirected output by redirecting the output of the parent process. You’ll have to figure out how to distinguish the output of the parent from the output of the child, but so too did human beings who ran the helper process manually, so presumably there’s some consistent way of recognizing it.

¹ Of course, that doesn’t stop a program from explicitly exposing a custom mechanism for allowing other processes to manipulate them.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

5 comments

Discussion is closed. Login to edit/delete existing comments.

Sort by :
  • Igor Levicki

    @Melissa P

    > Some processes are outside your scope, developed by 3rd parties that lack the experience to do it right.

    In my 15+ year experience, it's usually one of the following:

    - not understanding how 3rd party component is supposed to be used
    - unwillingness to license optional 3rd party component that already exists and does what you want
    - unwillingness to pay 3rd party change request to ease integration

    > Then you have either the option to add quirks or state that your software cannot handle that. That either means excessive work at other places to compensate, or losing...

    Read more
  • Joshua Hudson

    There once was a Visual Studio bug that was leaking directory handles. For this reason I have lying around the *correct* routine to replace a handle in a process without breaking anything, so yes I *can* swap out a process’s standard output handle. This probably won’t work very well here because the target process most likely will have generated output already.

    I recommend using a loopback ssh connection to gather the output.

  • Melissa P

    but you can inject a drone (remote thread) into the process and read the PEB for the standard handle values; in case of the mentioned issue that standard handles aren't used (read) anymore you can detect what mechanism (which standard lib) is writing into stdout/conout and proxy those methods to capture the output while keeping the existing writes intact -- so it's doable but very hacky and very program specific -- no generic solution but if the end justifies the means it is possible to do so ...

    ... done that once to "fix" broken process output that used their own...

    Read more
    • Igor Levicki

      Technically possible? Yes.

      But hear me out — requests like this come from managers who ask the dev to “just make it work”. Resulting kludges come from devs who can’t say “No” to such requests. I can understand when the reason is fearing for their job if they refuse, but worst kludges come from devs who think they are clever and treat it as a challenge — they are the most dangerous ones.

      • Melissa P

        It depends. In the end it's risk analysis. Some processes are outside your scope, developed by 3rd parties that lack the experience to do it right. Then you have either the option to add quirks or state that your software cannot handle that. That either means excessive work at other places to compensate, or losing customers.

        To put it in perspective: You can sell a car which only runs on perfectly maintained roads with perfect surfaces and markings. The question is if anyone will buy such a car or if authorities as a consequence will make every single road perfect. It's...

        Read more