I know that there're stdout/in/err for a program and I want to redirect a program's output to a file instead of the console output. And I now figure it out with the code below:
我知道程序中存在stdout / in / err,我想将程序的输出重定向到文件而不是控制台输出。我现在用下面的代码搞清楚:
FileStream fs = File.Open(@"E:\console.txt", FileMode.OpenOrCreate);StreamWriter sw = new StreamWriter(fs);TextWriter old = Console.Out;Console.SetOut(sw);Console.Write("bbb");sw.Flush();
But this approach is to connect the program's stdout to Console.Out and redirect the Console.Out to the file. It's kind of like this:
但是这种方法是将程序的stdout连接到Console.Out并将Console.Out重定向到文件。它有点像这样:
Program.StdOut -> Console.Out -> File
Program.StdOut - > Console.Out - >文件
The Console.Out here seems to be a bridge. I don't want this bridge and I don't want to use Console.Write() to make the output. How could I map the program's stdout stream to the target file directly and write to the program's stdout directly instead of Console.Write()? What I want is kind of like this:
Console.Out在这里似乎是一座桥梁。我不想要这个桥,我不想使用Console.Write()来输出。我怎么能直接将程序的stdout流映射到目标文件并直接写入程序的stdout而不是Console.Write()?我想要的是这样的:
Program.StdOut -> File
Program.StdOut - >文件
The Process.StandardOutput property only gives me a readonly StreamReader object. How to write to the Process.StandardOutput?? Or where is the program's stdout?
Process.StandardOutput属性只为我提供了一个只读StreamReader对象。如何写入Process.StandardOutput?或者程序的标准输出在哪里?
Many thanks.
3 个解决方案
#1
6
You can get a hold of the application's stdout by calling Console.OpenStandardOutput. From there, you can do whatever you want with the stream, although you won't be able to reassign it. If you want to do that you'll have to P/Invoke SetStdHandle and handle the details yourself.
您可以通过调用Console.OpenStandardOutput来获取应用程序的stdout。从那里,你可以用流做任何你想做的事,虽然你将无法重新分配它。如果你想这样做,你将需要P / Invoke SetStdHandle并自己处理细节。
EDIT: Added example code for the P/Invoke route:
编辑:添加了P / Invoke路由的示例代码:
[DllImport("kernel32.dll", SetLastError = true)][return: MarshalAs(UnmanagedType.Bool)]static extern bool SetStdHandle(int nStdHandle, IntPtr nHandle);const int STD_OUTPUT_HANDLE = -11;static void RedirectStandardOutput(FileStream file){ SetStdHandle(STD_OUTPUT_HANDLE, file.SafeFileHandle.DangerousGetHandle());}
#2
6
You probably shouldn't set the stdout of your own process. The reason it's stdout is so that the caller (command line, whatever) can redirect it wherever it needs to, without your program having to know.
您可能不应该设置自己进程的标准输出。它是stdout的原因是调用者(命令行,无论如何)可以在任何需要的地方重定向它,而无需程序必须知道。
That's how things like "type foo.txt | more" work. If the type command felt free to redefine stdout to a file, that wouldn't work at all.
这就是“输入foo.txt | more”之类的工作方式。如果type命令可以*地将stdout重新定义为文件,那么根本不起作用。
If you want to write to a stream, just open the stream and write to it.
如果要写入流,只需打开流并写入它即可。
#3
1
use ProcessStartInfo and Process classes and set RedirectStandardOutput to true, then you can capture the output from a stream.
使用ProcessStartInfo和Process类并将RedirectStandardOutput设置为true,然后您可以捕获流的输出。
ProcessStartInfo info = new ProcessStartInfo("process.exe", "-arg1 -arg2");info.RedirectStandardOutput = true;Process p = Process.Start(info);p.Start();string output = p.StandardOutput.ReadToEnd();
#1
6
You can get a hold of the application's stdout by calling Console.OpenStandardOutput. From there, you can do whatever you want with the stream, although you won't be able to reassign it. If you want to do that you'll have to P/Invoke SetStdHandle and handle the details yourself.
您可以通过调用Console.OpenStandardOutput来获取应用程序的stdout。从那里,你可以用流做任何你想做的事,虽然你将无法重新分配它。如果你想这样做,你将需要P / Invoke SetStdHandle并自己处理细节。
EDIT: Added example code for the P/Invoke route:
编辑:添加了P / Invoke路由的示例代码:
[DllImport("kernel32.dll", SetLastError = true)][return: MarshalAs(UnmanagedType.Bool)]static extern bool SetStdHandle(int nStdHandle, IntPtr nHandle);const int STD_OUTPUT_HANDLE = -11;static void RedirectStandardOutput(FileStream file){ SetStdHandle(STD_OUTPUT_HANDLE, file.SafeFileHandle.DangerousGetHandle());}
#2
6
You probably shouldn't set the stdout of your own process. The reason it's stdout is so that the caller (command line, whatever) can redirect it wherever it needs to, without your program having to know.
您可能不应该设置自己进程的标准输出。它是stdout的原因是调用者(命令行,无论如何)可以在任何需要的地方重定向它,而无需程序必须知道。
That's how things like "type foo.txt | more" work. If the type command felt free to redefine stdout to a file, that wouldn't work at all.
这就是“输入foo.txt | more”之类的工作方式。如果type命令可以*地将stdout重新定义为文件,那么根本不起作用。
If you want to write to a stream, just open the stream and write to it.
如果要写入流,只需打开流并写入它即可。
#3
1
use ProcessStartInfo and Process classes and set RedirectStandardOutput to true, then you can capture the output from a stream.
使用ProcessStartInfo和Process类并将RedirectStandardOutput设置为true,然后您可以捕获流的输出。
ProcessStartInfo info = new ProcessStartInfo("process.exe", "-arg1 -arg2");info.RedirectStandardOutput = true;Process p = Process.Start(info);p.Start();string output = p.StandardOutput.ReadToEnd();