You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中如何让cmd.exe输出同时显示在窗口并保存到变量

问题

我开发了一个用于下载和转换音频文件的简易XAML应用,点击下载按钮时会执行yt-dlp,通过ProcessStartInfo的RedirectStandardOutput属性捕获其输出并解析文件名供后续使用,但这样cmd.exe窗口不会打印任何内容。请问是否有办法既能让输出在cmd.exe窗口中打印,又能将输出保存到变量中?

以下是我的执行命令函数代码:

private void StartProcess(string args)
{
    Process process = new Process();
    {
        process.StartInfo = new ProcessStartInfo()
        {
            FileName = "cmd.exe",
            Arguments = args,
            UseShellExecute = false,
            RedirectStandardOutput = true,
            RedirectStandardError = true
        };
    }
    process.Start();
    string out = process.ReadToEnd();
    process.WaitForExit();
    return;
}
解决方案

要同时实现cmd窗口输出内容和捕获输出到变量,可以采用以下两种可行方案:

方案一:异步监听输出流,同时同步显示内容

取消阻塞式的ReadToEnd,改用异步监听进程的输出/错误流,一边将内容存入变量,一边将内容打印到控制台(或XAML应用的UI控件中模拟cmd输出效果)。同时设置CreateNoWindow=false确保cmd窗口正常显示:

private async Task<string> StartProcessAndCaptureOutput(string args)
{
    var outputBuilder = new StringBuilder();
    using (var process = new Process())
    {
        process.StartInfo = new ProcessStartInfo()
        {
            FileName = "cmd.exe",
            Arguments = args,
            UseShellExecute = false,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = false, // 显示cmd窗口
            StandardOutputEncoding = Encoding.UTF8,
            StandardErrorEncoding = Encoding.UTF8
        };

        // 监听标准输出
        process.OutputDataReceived += (sender, e) =>
        {
            if (!string.IsNullOrEmpty(e.Data))
            {
                outputBuilder.AppendLine(e.Data);
                Console.WriteLine(e.Data); // 同步打印到控制台,也可替换为UI控件更新
            }
        };

        // 监听错误输出
        process.ErrorDataReceived += (sender, e) =>
        {
            if (!string.IsNullOrEmpty(e.Data))
            {
                outputBuilder.AppendLine(e.Data);
                Console.WriteLine(e.Data);
            }
        };

        process.Start();
        // 启动异步读取流
        process.BeginOutputReadLine();
        process.BeginErrorReadLine();

        await process.WaitForExitAsync();
    }

    return outputBuilder.ToString(); // 返回捕获到的完整输出
}

注意:XAML应用中更新UI需要切换到主线程,可使用Dispatcher.Invoke来更新文本框等控件内容。

方案二:让yt-dlp同时输出到窗口和日志文件

修改yt-dlp的执行参数,让它将输出同时打印到cmd窗口和指定日志文件,之后读取日志文件内容到变量:

  1. 修改args参数,添加日志输出选项:
/c yt-dlp [你的下载参数] --log-file yt-dlp.log
  1. 进程结束后读取日志文件:
private void StartProcess(string args)
{
    Process process = new Process();
    process.StartInfo = new ProcessStartInfo()
    {
        FileName = "cmd.exe",
        Arguments = args,
        UseShellExecute = true, // 允许显示cmd窗口
        CreateNoWindow = false
    };
    process.Start();
    process.WaitForExit();

    // 读取日志文件内容到变量
    string output = File.ReadAllText("yt-dlp.log", Encoding.UTF8);
    // 后续可根据需要处理output,比如解析文件名
}

这种方式无需处理流监听,但要注意日志文件的覆盖、存储路径和清理问题。

内容的提问来源于stack exchange,提问作者BattleritePump

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 09:02:42