啟動外部主控台程式 (如 `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+ 建議指定 | 避免中文亂碼 (預設系統編碼頁) |
若子程式輸出格式固定 (如 `Progress: 45%`),可在 `onOutputLine` 解析數值並更新 `ProgressBar`。