在命令提示符中获取正在运行的Windows进程的控制台输出?将StreamReader指向命令提示符

7
我正在尝试确定在Windows环境下,通过C#获取已运行进程的命令提示符中的控制台输出的方法。我已经看到了针对Linux系统的解决方案 (通过Shell),以及检索Process对象的方法。虽然这两者都没有提供获取进程输出的解决方案。
在我的代码中,我目前通过以下方式找到一个进程(MongodDB守护程序)。
Process[] procs = Process.GetProcessesByName("mongod");
if (procs.Length > 0)
{
    MongoProcess = procs[0];
    Console.Out.WriteLine("Found mongod.exe, process id: " + MongoProcess.Id);
}

我还发现了Process.StandardOutput属性,它提供了“可以用来读取应用程序标准输出流的StreamReader”。

有没有办法将这个StreamReader输入直接定向到命令提示符输出?

我也知道我可以启动一个进程并显示命令提示符(进程输出),但这只有在进程是由“我”启动时才能实现。

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

我知道我可以直接使用StreamReader读取并以自己的方式显示输出,但我真的更喜欢显示命令提示符。


“命令提示符”是什么意思?控制台窗口吗?(“命令提示符”这个短语指的是cmd.exe要求您输入命令时在控制台窗口中出现的文本,例如 C:\Users\whatever>) - Harry Johnston
是的,控制台窗口。 - KDecker
即使有了这个修正,我发现我仍然不确定你想做什么。如果MongoDB进程已经生成控制台输出,那么你通过将其发送到不同的控制台来实现什么目的?如果没有,你实际上想要捕获什么输出?(顺便说一下,你只能在自己创建的进程中使用Process.StandardOutput。) - Harry Johnston
我并不一定想将输出重定向到另一个/单独的控制台,我只是想在控制台中显示它。如果进程在我的应用程序之前启动,而没有控制台,则无法(我所知道的)在控制台中查看其输出。我不想从其输出中捕获任何内容,我只想查看它,以便在运行时监视它。//虽然我猜如果我不能从我没有启动的进程中访问Process.StandardOutput,那么可能是不可能的。 - KDecker
例如,如果我通过双击桌面上的快捷方式启动Firefox,则不会弹出控制台并显示进程输出。但是,如果我通过命令行启动它,则可以在运行时查看进程输出。// 在我的情况下,Mongod.exe可以通过命令行启动,我可以看到输出,但如果它在我的应用程序启动之前已经运行(并且从未显示过控制台),则我无法看到进程输出。// 重新表达我的OP“如果Firefox已经运行并且从未显示控制台,我如何查看其控制台输出?” - KDecker
由于Firefox是一个GUI应用程序,似乎不太可能有任何输出。 (虽然我想它可能从Linux版本中继承了一些printf或其他调用。)但即使给定一个生成标准输出的应用程序,如果进程没有被创建为控制台(因此没有标准输出句柄),那么没有任何简单或支持的方法来事后给它一个控制台。 - Harry Johnston
1个回答

8

如果一个进程在创建时没有标准输出句柄,Windows不提供任何机制来事后给予它。 (此外,在大多数情况下,应用程序仅在启动期间检查标准输出句柄。)

如果你知道(或可以成功猜测)特定应用程序如何生成输出,原则上可能通过将自己的代码注入到该进程中来开始捕获该输出。例如,如果你知道应用程序使用C++并动态链接到VS2015运行库,你可以注入调用freopen的代码,如此处所示。(在这种情况下,你必须知道应用程序使用的运行库,因为在查找freopen的地址时必须指定它。)

然而,代码注入并不是简单的,会导致意外地使进程发生故障。此外,已经生成的任何输出几乎肯定已被丢弃并且无法挽回地丢失。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接