如何用C#结合自定义DLL实现控制台与TextBox的双向重定向?
解决方案:C#双向控制台与TextBox同步(自定义DLL实现)
嘿,我来帮你搞定这个双向控制台同步的问题!你已经完成了创建控制台窗口的部分,现在只需要补全控制台输出到TextBox2的实时同步逻辑,同时保证UI不会卡顿。下面是完整的解决方案,包含你的DLL实现和WinForm调用代码:
第一步:完善你的自定义DLL
在你的DLL项目中,添加以下代码来封装控制台重定向和双向同步的逻辑:
using System; using System.IO; using System.Runtime.InteropServices; using System.Windows.Forms; namespace YourCustomDll { // 原生API调用封装 public static class NativeMethods { public const int STD_OUTPUT_HANDLE = -11; [DllImport("kernel32.dll")] public static extern IntPtr GetStdHandle(int nStdHandle); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool AllocConsole(); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool FreeConsole(); } // 控制台重定向核心类,实现双向同步 public class ConsoleSyncManager : IDisposable { private readonly TextBox _outputTextBox; private readonly TextWriter _originalConsoleOut; private bool _isDisposed = false; public ConsoleSyncManager(TextBox outputTextBox) { _outputTextBox = outputTextBox; // 创建控制台窗口 if (!NativeMethods.AllocConsole()) throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); // 保存原始控制台输出流 _originalConsoleOut = Console.Out; // 重定向Console输出到自定义Writer,同时同步到TextBox Console.SetOut(new DualOutputWriter(_originalConsoleOut, UpdateTextBox)); } // 跨线程安全更新TextBox2 private void UpdateTextBox(string content) { if (_outputTextBox.InvokeRequired) { _outputTextBox.Invoke(new Action<string>(UpdateTextBox), content); return; } // 追加内容并自动滚动到底部 _outputTextBox.AppendText(content); _outputTextBox.SelectionStart = _outputTextBox.Text.Length; _outputTextBox.ScrollToCaret(); } // 将TextBox1的内容发送到控制台 public void SendInputToConsole(string inputText) { if (!string.IsNullOrWhiteSpace(inputText)) { Console.WriteLine(inputText); } } // 释放资源,恢复原始状态 public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (_isDisposed) return; if (disposing) { // 恢复原始控制台输出流 Console.SetOut(_originalConsoleOut); } // 关闭控制台窗口 NativeMethods.FreeConsole(); _isDisposed = true; } } // 自定义TextWriter,同时输出到控制台和TextBox internal class DualOutputWriter : TextWriter { private readonly TextWriter _consoleWriter; private readonly Action<string> _textBoxUpdater; public DualOutputWriter(TextWriter consoleWriter, Action<string> textBoxUpdater) { _consoleWriter = consoleWriter; _textBoxUpdater = textBoxUpdater; } public override Encoding Encoding => _consoleWriter.Encoding; public override void Write(char value) { _consoleWriter.Write(value); _textBoxUpdater(value.ToString()); } public override void Write(string value) { _consoleWriter.Write(value); _textBoxUpdater(value); } public override void WriteLine(string value) { _consoleWriter.WriteLine(value); _textBoxUpdater(value + Environment.NewLine); } } }
第二步:在WinForm项目中使用DLL
- 先添加对自定义DLL的引用。
- 在你的Form类中,添加以下代码来绑定按钮和TextBox的逻辑:
using YourCustomDll; using System; using System.Windows.Forms; namespace YourWinFormApp { public partial class MainForm : Form { private ConsoleSyncManager _consoleSyncManager; public MainForm() { InitializeComponent(); } // 按钮1:初始化控制台同步(比如命名为btnInitConsole) private void btnInitConsole_Click(object sender, EventArgs e) { try { _consoleSyncManager = new ConsoleSyncManager(textBox2); textBox2.AppendText("控制台已启动,开始同步输出!" + Environment.NewLine); } catch (Exception ex) { MessageBox.Show($"初始化失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } // 按钮2:发送TextBox1内容到控制台(比如命名为btnSendToConsole) private void btnSendToConsole_Click(object sender, EventArgs e) { _consoleSyncManager?.SendInputToConsole(textBox1.Text); textBox1.Clear(); // 可选:发送后清空输入框 } // 窗体关闭时释放资源 private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { _consoleSyncManager?.Dispose(); } } }
关键逻辑说明
- DualOutputWriter:这是实现双向同步的核心,它继承自
TextWriter,每次写入内容时会同时输出到原始控制台窗口和调用更新TextBox的方法,确保两边内容一致。 - 跨线程安全:因为控制台输出可能来自非UI线程,所以更新TextBox时必须使用
Invoke方法,避免跨线程操作UI的异常。 - 资源管理:实现
IDisposable接口,在窗体关闭时恢复原始控制台输出流并关闭控制台窗口,防止资源泄漏。 - 实时同步:所有通过
Console.WriteLine输出的内容(包括你从TextBox1发送的内容,以及程序其他地方的控制台输出)都会自动同步到TextBox2,完全满足你“持续运行”的需求。
内容的提问来源于stack exchange,提问作者Rasuljon
相关产品推荐
相关产品推荐

