首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 重導向主控台程式輸出至 WinForms (Process + RedirectStandardOutput)

     編輯:關於C語言

啟動外部主控台程式 (如 `ipconfig`、`ping`、自建工具) 並即時捕獲其標準輸出到 WinForms 介面,核心在於 `ProcessStartInfo.RedirectStandardOutput = true`。

完整範例


using System;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;

public partial class Form1 : Form
{
    public Form1() => InitializeComponent();

    private void BtnRun_Click(object sender, EventArgs e)
    {
        ExecuteCommand("ipconfig", "", line => AppendOutput(line));
    }

    private void ExecuteCommand(string fileName, string args, Action onOutputLine)
    {
        var psi = new ProcessStartInfo
        {
            FileName = fileName,
            Arguments = args,
            UseShellExecute = false,          // 必須 false 才能重導向
            RedirectStandardOutput = true,    // 捕獲 stdout
            RedirectStandardError = true,     // 可選:捕獲 stderr
            CreateNoWindow = true,            // 不顯示主控台視窗
            WindowStyle = ProcessWindowStyle.Hidden,
            StandardOutputEncoding = Encoding.UTF8, // .NET Core 3.0+ 指定編碼
            StandardErrorEncoding = Encoding.UTF8
        };

        using (var proc = Process.Start(psi))
        {
            if (proc == null) return;

            // 非同步讀取避免死結 (同步 ReadLine 也可,但需注意緩衝區滿阻塞)
            proc.OutputDataReceived += (s, e) => { if (e.Data != null) onOutputLine(e.Data); };
            proc.ErrorDataReceived += (s, e) => { if (e.Data != null) onOutputLine("[ERR] " + e.Data); };

            proc.BeginOutputReadLine();
            proc.BeginErrorReadLine();

            proc.WaitForExit(); // 同步等待結束;UI 執行緒會阻塞,實務建議用 Task.Run 包裝
        }
    }

    private void AppendOutput(string line)
    {
        if (InvokeRequired)
            Invoke(new Action(AppendOutput), line);
        else
            txtOutput.AppendText(line + Environment.NewLine);
    }
}

關鍵設定對照

屬性必要性說明
UseShellExecute**必須 false**true 時由 Shell 執行,無法重導向標準流
RedirectStandardOutput**必須 true**啟用 stdout 管道
CreateNoWindow建議 true不彈出黑框視窗
StandardOutputEncoding.NET Core 3.0+ 建議指定避免中文亂碼 (預設系統編碼頁)

常見坑與解法

  1. 死結:同步 `ReadToEnd()` / `ReadLine()` 若緩衝區滿 (4KB) 且未讀取,子進程寫入阻塞 → 父進程等待結束 → 互相等待。
    **解法**:使用非同步事件 `OutputDataReceived` / `ErrorDataReceived` + `BeginOutputReadLine()`。
  2. 編碼亂碼:子程式輸出編碼 (CP950/CP437/UTF-8) 與父程式讀取編碼不符。
    **解法**:指定 `StandardOutputEncoding`,或子程式輸出前 `chcp 65001` (UTF-8)。
  3. UI 凍結:`WaitForExit()` 阻塞 UI 執行緒。
    **解法**:`Task.Run(() => ExecuteCommand(...))` 或 `proc.EnableRaisingEvents = true` + `proc.Exited` 事件。
  4. 互動式程式:需輸入密碼/確認的程式 (如 `runas`、資料庫工具) 需 `RedirectStandardInput = true` 並寫入 `StandardInput.WriteLine()`。

進階:即時顯示進度列

若子程式輸出格式固定 (如 `Progress: 45%`),可在 `onOutputLine` 解析數值並更新 `ProgressBar`。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved