ZBLOG

这样测试发现关闭时窗口一直在等待关闭,而cmdProcess已经执行完了

如果在关闭窗口时发现程序一直在等待,而 cmdProcess 已经执行完,可能是因为我们没有适当地检查进程的状态或者处理输出流。为了改善这一点,可以在窗体关闭时确保强制终止任何正在运行的子进程,并优化事件处理。

以下是一个改进版代码示例:

改进后的代码示例

  1. using System;
  2. using System.Diagnostics;
  3. using System.Windows.Forms;
  4. namespace CmdExecutor
  5. {
  6. public partial class MainForm : Form
  7. {
  8. private Process cmdProcess;
  9. public MainForm()
  10. {
  11. InitializeComponent();
  12. }
  13. private void btnExecute_Click(object sender, EventArgs e)
  14. {
  15. ExecuteCommand("your_command_here"); // 替换成您想要执行的CMD命令
  16. }
  17. private void ExecuteCommand(string command)
  18. {
  19. cmdProcess = new Process();
  20. cmdProcess.StartInfo.FileName = "cmd.exe";
  21. cmdProcess.StartInfo.Arguments = "/C " + command; // /C 表示执行完命令后终止CMD
  22. cmdProcess.StartInfo.RedirectStandardOutput = true; // 重定向输出流
  23. cmdProcess.StartInfo.UseShellExecute = false; // 不使用操作系统外壳启动进程
  24. cmdProcess.StartInfo.CreateNoWindow = true; // 不创建窗口
  25. cmdProcess.OutputDataReceived += CmdProcess_OutputDataReceived; // 添加事件处理器
  26. try
  27. {
  28. cmdProcess.Start(); // 启动进程
  29. cmdProcess.BeginOutputReadLine(); // 开始异步读取输出
  30. cmdProcess.EnableRaisingEvents = true; // 启用事件支持
  31. cmdProcess.Exited += (s, args) =>
  32. {
  33. MessageBox.Show("命令执行完毕!");
  34. // 这里可以添加其他逻辑,比如更新UI等。
  35. };
  36. }
  37. catch (Exception ex)
  38. {
  39. MessageBox.Show($"启动命令失败: {ex.Message}");
  40. }
  41. }
  42. private void CmdProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
  43. {
  44. if (!string.IsNullOrEmpty(e.Data))
  45. {
  46. AppendTextToTextBox(e.Data);
  47. }
  48. }
  49. private void AppendTextToTextBox(string text)
  50. {
  51. if (textBoxOutput.InvokeRequired)
  52. {
  53. textBoxOutput.Invoke(new Action<string>(AppendTextToTextBox), text);
  54. return;
  55. }
  56. textBoxOutput.AppendText(text + Environment.NewLine);
  57. textBoxOutput.ScrollToCaret(); // 滚动到文本框底部以查看最新输出
  58. }
  59. protected override void OnFormClosing(FormClosingEventArgs e)
  60. {
  61. base.OnFormClosing(e);
  62. if (cmdProcess != null && !cmdProcess.HasExited)
  63. {
  64. var result = MessageBox.Show("正在执行CMD命令,确认要关闭吗?", "确认", MessageBoxButtons.YesNo);
  65. if (result == DialogResult.Yes)
  66. {
  67. try
  68. {
  69. if (!cmdProcess.HasExited)
  70. {
  71. cmdProcess.Kill(); // 强制终止进程
  72. cmdProcess.WaitForExit(); // 等待进程完全退出,确保释放资源
  73. }
  74. }
  75. catch (Exception ex)
  76. {
  77. MessageBox.Show($"无法终止进程: {ex.Message}");
  78. }
  79. }
  80. else
  81. {
  82. e.Cancel = true; // 取消关闭操作,如果用户选择不关闭。
  83. }
  84. }
  85. }
  86. }
  87. }

改动说明:

  1. 启用事件支持:通过设置 EnableRaisingEventstrue,我们能够订阅 Exited 事件,这样可以更好地处理过程结束后所需进行的操作,例如通知用户。

  2. 简单判断和直接杀死:在检查 HasExited 后,在需要的情况下立即杀死 CMD 进程。这样避免了长时间等待的问题。

  3. 信息反馈:提供反馈给用户,比如在命令完成后显示提示信息,提升用户体验。

这些改动能帮助减少因未及时响应而导致的窗体锁定问题,同时提供清晰的信息与控制。当 CMD 命令完成或被强制终止时,你都能获得适当的反馈。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=19541

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?