7

I am trying to determine if there is a way to get the console output, in a command prompt, of an already running process in the windows environment via C#. I have seen an answer for linux based systems through the shell and also a way to retrieve a Process object. Though neither offer a solution to get the output of the process.

I my code I currently find a process (MongodDB daemon) this way

Process[] procs = Process.GetProcessesByName("mongod");
if (procs.Length > 0)
{
    MongoProcess = procs[0];
    Console.Out.WriteLine("Found mongod.exe, process id: " + MongoProcess.Id);
}

I have also found the Process.StandardOutput property which supplies "A StreamReader that can be used to read the standard output stream of the application.". Is there a way to direct this StreamReader input to a command prompt output?

I also know that I can start a process and display the command prompt (process output), but this is only when the process is started "by me".

Process.Start(new ProcessStartInfo("notepad.exe") { CreateNoWindow = false })

I also know that I could simply read from the StreamReader and display the output in my own way, but I would really prefer to just display a command prompt.

Community
  • 1
  • 1
KDecker
  • 6,928
  • 8
  • 40
  • 81
  • What do you mean by "command prompt"? A console window? (The phrase "command prompt" means the text that appears in the console window when cmd.exe wants you to enter a command, e.g., `C:\Users\whatever>`) – Harry Johnston Mar 31 '16 at 05:11
  • Yes, console window. – KDecker Mar 31 '16 at 12:46
  • Even with that correction, I find I'm still unsure as to what you're trying to do. If the MongoDB process is already generating console output, what are you trying to achieve by sending it to a different console? If it isn't, what output are you actually trying to capture? (You can only use `Process.StandardOutput` with processes you created yourself, by the way.) – Harry Johnston Mar 31 '16 at 21:19
  • I am not necessarily trying to redirect the output to a different/separate console, I simply want to display it in a console. If the process was started prior to my application, without a console, then there is no way (I know of) to view its output in a console. I am not trying to capture anything from its output, I simply want to view it so I can monitor it as it runs. // Though I guess if I cannot access `Process.StandardOutput` from processes I didn't start it might not be possible. – KDecker Apr 01 '16 at 12:50
  • For example, if I startup Firefox by double cliking the shortcut on my desktop a console does not popup and show me the process output. But if I start it via the command line then I can view the process output as it is running. // In my case Mongod.exe can be started via the command line and I can see the output, but if it is already running prior to my application startup (and the console was never displayed) then I cannot see the process output. // To rephrase my OP "How can I view Firefox's console output if it is already running and never displayed the console?". – KDecker Apr 01 '16 at 13:04
  • Since Firefox is a GUI application, it seems unlikely that there *is* any output to begin with. (Though I suppose it might have inherited some calls to printf or whatever from the Linux version.) But even given an application that does generate standard output, if the process has been created without a console (and hence without a standard output handle) there isn't any straightforward or supported way to retroactively give it one. – Harry Johnston Apr 01 '16 at 22:27

1 Answers1

8

Windows does not provide any mechanism to retroactively give another process a standard output handle if it was created without one. (Besides, in most cases an application will check the standard output handle only during startup.)

If you know (or can successfully guess) how a specific application generates output, it may in principle be possible to start capturing that output by injecting your own code into the process. For example, if you know that the application uses C++ and is dynamically linked to the VS2015 runtime library, you might inject code that calls freopen as shown here. (In this scenario, you must know which runtime library the application uses because you have specify it when looking up the address for freopen.)

However, code injection is not trivial, and creates a risk of inadvertently causing the process to malfunction. Also, any output that has already been generated will almost certainly have been discarded and be irrevocably lost.

Community
  • 1
  • 1
Harry Johnston
  • 35,639
  • 6
  • 68
  • 158