当前位置: 首页 > news >正文

C#基础(③CMD进程)

在 C# 中,打开和显示 CMD 进程主要通过 System.Diagnostics.Process 类实现,核心是配置进程启动信息并处理其输入输出。以下结合代码细节说明具体实现方式:

1. 启动 CMD 进程(隐藏原始窗口)

代码通过 ProcessStartInfo 配置 CMD 进程的启动参数,关键是隐藏原始 CMD 窗口并重定向输入输出:

// 配置进程启动信息
ProcessStartInfo startInfo = new ProcessStartInfo
{FileName = "cmd.exe",  // 指定要启动的程序为CMDUseShellExecute = false,  // 禁用外壳程序,允许重定向输入输出RedirectStandardInput = true,  // 重定向标准输入(允许向CMD发送命令)RedirectStandardOutput = true, // 重定向标准输出(捕获CMD的执行结果)RedirectStandardError = true,  // 重定向错误输出(捕获错误信息)CreateNoWindow = true,  // 不显示CMD的原始窗口StandardOutputEncoding = Encoding.Default,  // 匹配系统默认编码StandardErrorEncoding = Encoding.Default
};// 创建进程对象并关联配置
_cmdProcess = new Process
{StartInfo = startInfo,EnableRaisingEvents = true  // 允许触发进程事件(如输出数据时)
};// 启动进程
_cmdProcess.Start();

核心逻辑

通过 CreateNoWindow = true 隐藏原始 CMD 窗口,同时通过 Redirect... 系列属性将 CMD 的输入输出 "接管" 过来,让程序可以直接与 CMD 交互,而无需显示其默认窗口。

2. 显示 CMD 输出(在自定义界面中)

虽然 CMD 本身的窗口被隐藏了,但代码通过以下方式将其输出显示在自定义的富文本框中:

监听 CMD 的输出事件

// 绑定输出事件:当CMD有正常输出时触发
_cmdProcess.OutputDataReceived += (s, e) =>
{if (!string.IsNullOrEmpty(e.Data))AppendOutput(e.Data);  // 显示正常输出
};// 绑定错误事件:当CMD有错误输出时触发
_cmdProcess.ErrorDataReceived += (s, e) =>
{if (!string.IsNullOrEmpty(e.Data))AppendOutput(e.Data, true);  // 显示错误输出(标红)
};// 开始异步读取输出(必须调用,否则事件不会触发)
_cmdProcess.BeginOutputReadLine();
_cmdProcess.BeginErrorReadLine();

逻辑
CMD 执行命令后的结果会通过 OutputDataReceived(正常结果)和 ErrorDataReceived(错误信息)事件传递给程序,代码通过绑定这两个事件捕获输出内容。

将输出显示到界面控件

private void AppendOutput(string text, bool isError = false)
{// 跨线程安全检查:如果是后台线程调用,切换到UI线程if (outputRichTextBox.InvokeRequired){outputRichTextBox.Invoke(new Action<string, bool>(AppendOutput), text, isError);return;}// 设置文本颜色(错误信息标红)outputRichTextBox.SelectionColor = isError ? Color.Red : outputRichTextBox.ForeColor;outputRichTextBox.AppendText(text + Environment.NewLine);  // 添加到富文本框outputRichTextBox.ScrollToCaret();  // 自动滚动到最新内容
}

逻辑
捕获到的 CMD 输出通过 AppendOutput 方法显示在 outputRichTextBox 中,并且用颜色区分正常信息(默认色)和错误信息(红色),实现了 "自定义显示 CMD 内容" 的效果。

总结流程
隐藏启动 CMD:通过 ProcessStartInfo 配置 CreateNoWindow = true 隐藏原始窗口,同时重定向输入输出。
捕获输出:通过 OutputDataReceived 和 ErrorDataReceived 事件监听 CMD 的所有输出。
自定义显示:将捕获的输出通过富文本框展示,并添加颜色区分等增强功能。

核心代码

using System;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace cmdtest
{public partial class Form1 : Form{// 声明进程对象用于控制终端private Process _cmdProcess;// 声明控件private RichTextBox outputRichTextBox;private TextBox commandTextBox;private Button sendButton;public Form1(){InitializeComponents(); // 初始化所有控件和事件InitializeCmdProcess(); // 启动终端进程}// 初始化所有控件和事件绑定private void InitializeComponents(){// 配置输出富文本框outputRichTextBox = new RichTextBox{Multiline = true,ScrollBars = RichTextBoxScrollBars.Vertical,ReadOnly = true,Location = new Point(20, 20),Size = new Size(740, 300),Text = "终端已启动,等待命令...\r\n"};// 配置命令输入框commandTextBox = new TextBox{Location = new Point(20, 340),Size = new Size(645, 25)};commandTextBox.KeyDown += CommandTextBox_KeyDown; // 绑定Enter键事件// 配置发送按钮sendButton = new Button{Location = new Point(680, 340),Size = new Size(80, 25),Text = "发送",UseVisualStyleBackColor = true};sendButton.Click += SendButton_Click; // 绑定点击事件// 配置窗体this.ClientSize = new Size(784, 381);this.Text = "CMD 控制器";this.FormClosing += Form1_FormClosing; // 绑定窗体关闭事件// 将控件添加到窗体this.Controls.Add(outputRichTextBox);this.Controls.Add(commandTextBox);this.Controls.Add(sendButton);}// 初始化命令行进程private void InitializeCmdProcess(){ProcessStartInfo startInfo = new ProcessStartInfo{FileName = "cmd.exe",UseShellExecute = false,RedirectStandardInput = true,RedirectStandardOutput = true,RedirectStandardError = true,CreateNoWindow = true,StandardOutputEncoding = Encoding.Default,StandardErrorEncoding = Encoding.Default};_cmdProcess = new Process{StartInfo = startInfo,EnableRaisingEvents = true};// 绑定输出事件_cmdProcess.OutputDataReceived += (s, e) =>{if (!string.IsNullOrEmpty(e.Data))AppendOutput(e.Data);};_cmdProcess.ErrorDataReceived += (s, e) =>{if (!string.IsNullOrEmpty(e.Data))AppendOutput(e.Data, true);};// 启动进程try{_cmdProcess.Start();_cmdProcess.BeginOutputReadLine();_cmdProcess.BeginErrorReadLine();}catch (Exception ex){AppendOutput($"启动终端失败: {ex.Message}", true);}}// 向输出框添加内容(支持颜色区分)private void AppendOutput(string text, bool isError = false){// 跨线程安全更新UIif (outputRichTextBox.InvokeRequired){outputRichTextBox.Invoke(new Action<string, bool>(AppendOutput), text, isError);return;}// 设置文本颜色(错误信息为红色)outputRichTextBox.SelectionColor = isError ? Color.Red : outputRichTextBox.ForeColor;outputRichTextBox.AppendText(text + Environment.NewLine);outputRichTextBox.ScrollToCaret(); // 滚动到最新内容}// 发送命令按钮点击事件private void SendButton_Click(object sender, EventArgs e){SendCommand();}// 命令输入框按Enter键事件private void CommandTextBox_KeyDown(object sender, KeyEventArgs e){if (e.KeyCode == Keys.Enter){SendCommand();e.SuppressKeyPress = true; // 阻止系统提示音}}// 发送命令到终端private void SendCommand(){string command = commandTextBox.Text.Trim();if (string.IsNullOrEmpty(command)) return;if (_cmdProcess != null && !_cmdProcess.HasExited){try{AppendOutput("> " + command); // 显示输入的命令_cmdProcess.StandardInput.WriteLine(command); // 发送命令commandTextBox.Clear(); // 清空输入框}catch (Exception ex){AppendOutput($"发送命令失败: {ex.Message}", true);}}else{AppendOutput("终端已关闭,无法发送命令", true);}}// 窗体关闭事件:清理终端进程private void Form1_FormClosing(object sender, FormClosingEventArgs e){if (_cmdProcess != null && !_cmdProcess.HasExited){try{_cmdProcess.StandardInput.WriteLine("exit"); // 发送退出命令_cmdProcess.WaitForExit(1000); // 等待正常退出if (!_cmdProcess.HasExited)_cmdProcess.Kill(); // 强制关闭}catch { }finally{_cmdProcess.Dispose(); // 释放资源}}}}
}

123

http://www.dtcms.com/a/359643.html

相关文章:

  • 【C2000】C2000的国产替代现状与技术关键路径
  • unity3d 中 R3 实际使用 安装方法
  • 吴恩达机器学习作业十 PCA主成分分析
  • 【量化回测】backtracker整体架构和使用示例
  • arm容器启动spring-boot端口报错
  • linux 内核 - 常见的文件系统介绍
  • 【K8s】整体认识K8s之存储--volume
  • shell脚本(略)
  • 【Flink】并行度的设置
  • nrf52840 flash 分区
  • 3【鸿蒙/OpenHarmony/NDK】如何在鸿蒙应用中使用NDK?
  • 线阵相机和镜头选型案例介绍
  • 【不懂就问】-手机相关学习
  • 打开多个Excel文件后快速关闭所有的文档,并且退出Excel应用
  • Docker一小时快速上手(附报错解决方式)
  • 并发编程——11 并发容器(Map、List、Set)实战及其原理分析
  • deep seek的对话记录如何导出
  • CICD实战(1) - 使用Arbess+GitPuk+Docker快速实现项目打包构建、docker部署
  • 视频理解与行为识别全景综述
  • 计算机网络:(十六)TCP 的运输连接管理
  • 传统数据库out啦!KINGBASE ES V9R1C10 开启国产数据库“修仙”新纪元!
  • Redis六大常见命令详解:从set/get到过期策略的全方位解析
  • 大模型推理技术解析
  • AI热点周报(8.24~8.30):Grok 2.5开源,OpenAI Realtime正式商用,Meta或与OpenAI或Google合作?
  • 学习记录(二十二)--Overleaf中生成的PDF左上角1.5em问题
  • 【stm32】对射式红外传感器计次以及旋转编码器计次
  • 基于单片机智能大棚/温室大棚/智慧农业/智能栽培种植系统/温湿度控制
  • 使用VBA实现快速多重数据筛选
  • Flink部署实战:从入门到优化
  • 第 14 篇:K-Means与聚类思维——当AI在没有“标准答案”的世界里寻宝