用RedirectStandardOutput保存控制台文本

本文关键字:文本 控制台 保存 RedirectStandardOutput | 更新日期: 2023-09-27 18:12:46

我正在创建一个windows窗体应用程序,我正试图从控制台应用程序获得输出,同时保持在应用程序上打印输出。

我尝试创建一个进程,将RedirectStandardOutput设置为true,将ExecuteShell设置为false,然后我开始了一个异步读取操作,该操作工作完美,问题是我的应用程序"窃取"了应用程序的输出,因此输出不再显示在应用程序中。

是否有任何方法可以捕获输出,同时将输出保留在控制台应用程序上?我正在考虑捕获输出,然后将所有输出发送回应用程序的输出流,但我不知道如何实现这一点。

提前感谢,

杰米

用RedirectStandardOutput保存控制台文本

本机方法AllocConsole和FreeConsole可用于为任何正在运行的进程创建和销毁控制台,并且子控制台进程默认情况下将使用父控制台(它们不会创建无用的额外浮动控制台窗口),因此您可以将控制台附加到自己的进程,启动子进程,然后将输出写入新分配的控制台以完成您要完成的任务。如果您还需要用户能够向控制台应用程序提供输入,那么解决方案可能会有些复杂,但仍然可以将一些东西组合在一起,启动一个单独的线程,将控制台输入传递给子进程。关于此实现的另一个很好的细节是,如果您愿意,可以将控制台及其输出保持在子进程出口之后。

下面的表单有两个按钮,但为了使示例代码简洁,我不包括按钮本身,只包括它们的单击事件。

public partial class RunForm : Form
{
    public RunForm()
    {
        InitializeComponent();
    }
    private void runButton_Click(object sender, EventArgs e)
    {
        NativeMethods.AllocConsole();
        using (Process process = new Process())
        {
            process.StartInfo.FileName = "cmd.exe";
            process.StartInfo.Arguments = "/c echo Hello world!";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.Start();
            process.OutputDataReceived += process_OutputDataReceived;
            process.BeginOutputReadLine();
        }
    }
    void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        Console.WriteLine(e.Data);
        // do other things with the output here
    }
    private void closeConsoleButton_Click(object sender, EventArgs e)
    {
        NativeMethods.FreeConsole();
    }
}
internal static class NativeMethods
{
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool AllocConsole();
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool FreeConsole();
}