如果在关闭窗口时发现程序一直在等待,而 cmdProcess
已经执行完,可能是因为我们没有适当地检查进程的状态或者处理输出流。为了改善这一点,可以在窗体关闭时确保强制终止任何正在运行的子进程,并优化事件处理。
以下是一个改进版代码示例:
改进后的代码示例
using System;
using System.Diagnostics;
using System.Windows.Forms;
namespace CmdExecutor
{
public partial class MainForm : Form
{
private Process cmdProcess;
public MainForm()
{
InitializeComponent();
}
private void btnExecute_Click(object sender, EventArgs e)
{
ExecuteCommand("your_command_here"); // 替换成您想要执行的CMD命令
}
private void ExecuteCommand(string command)
{
cmdProcess = new Process();
cmdProcess.StartInfo.FileName = "cmd.exe";
cmdProcess.StartInfo.Arguments = "/C " + command; // /C 表示执行完命令后终止CMD
cmdProcess.StartInfo.RedirectStandardOutput = true; // 重定向输出流
cmdProcess.StartInfo.UseShellExecute = false; // 不使用操作系统外壳启动进程
cmdProcess.StartInfo.CreateNoWindow = true; // 不创建窗口
cmdProcess.OutputDataReceived += CmdProcess_OutputDataReceived; // 添加事件处理器
try
{
cmdProcess.Start(); // 启动进程
cmdProcess.BeginOutputReadLine(); // 开始异步读取输出
cmdProcess.EnableRaisingEvents = true; // 启用事件支持
cmdProcess.Exited += (s, args) =>
{
MessageBox.Show("命令执行完毕!");
// 这里可以添加其他逻辑,比如更新UI等。
};
}
catch (Exception ex)
{
MessageBox.Show($"启动命令失败: {ex.Message}");
}
}
private void CmdProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (!string.IsNullOrEmpty(e.Data))
{
AppendTextToTextBox(e.Data);
}
}
private void AppendTextToTextBox(string text)
{
if (textBoxOutput.InvokeRequired)
{
textBoxOutput.Invoke(new Action<string>(AppendTextToTextBox), text);
return;
}
textBoxOutput.AppendText(text + Environment.NewLine);
textBoxOutput.ScrollToCaret(); // 滚动到文本框底部以查看最新输出
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
if (cmdProcess != null && !cmdProcess.HasExited)
{
var result = MessageBox.Show("正在执行CMD命令,确认要关闭吗?", "确认", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
try
{
if (!cmdProcess.HasExited)
{
cmdProcess.Kill(); // 强制终止进程
cmdProcess.WaitForExit(); // 等待进程完全退出,确保释放资源
}
}
catch (Exception ex)
{
MessageBox.Show($"无法终止进程: {ex.Message}");
}
}
else
{
e.Cancel = true; // 取消关闭操作,如果用户选择不关闭。
}
}
}
}
}
改动说明:
启用事件支持:通过设置
EnableRaisingEvents
为true
,我们能够订阅Exited
事件,这样可以更好地处理过程结束后所需进行的操作,例如通知用户。简单判断和直接杀死:在检查
HasExited
后,在需要的情况下立即杀死 CMD 进程。这样避免了长时间等待的问题。信息反馈:提供反馈给用户,比如在命令完成后显示提示信息,提升用户体验。
这些改动能帮助减少因未及时响应而导致的窗体锁定问题,同时提供清晰的信息与控制。当 CMD 命令完成或被强制终止时,你都能获得适当的反馈。
内容由零声教学AI助手提供,问题来源于学员提问