C# WPF点击按钮启动进程后无法通过另一按钮终止问题
问题原因
你当前代码中_process变量存储的是你启动的cmd.exe进程实例,调用Kill()方法只会终止cmd进程本身,不会连带终止cmd启动的子进程Miner.exe,所以会出现停止按钮点击后目标进程仍在运行的情况。
解决方案
有两种常用实现方式,可按需选择:
方案1:直接启动目标exe,不经过cmd中转(推荐)
该方案不需要处理子进程关联逻辑,直接持有Miner进程的实例,Kill操作可以直接作用于目标进程:
private Process _process; private void StartProcess(object sender, RoutedEventArgs e) { // 直接启动Miner.exe,不需要走cmd中转 _process = new Process(); _process.StartInfo.FileName = @".\Miners\CryptoMiner1\Miner.exe"; // 可选:显式设置工作目录,避免相对路径找不到文件 // _process.StartInfo.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory; _process.Start(); } private void StopProcess(object sender, RoutedEventArgs e) { if (_process != null && !_process.HasExited) { _process.Kill(); // 等待进程退出后释放资源 _process.WaitForExit(); _process.Dispose(); _process = null; } }
方案2:必须走cmd启动时,终止整个进程树
如果有特殊需求必须通过cmd启动进程,就需要在停止时终止cmd进程关联的整个进程树,实现方法如下:
using System.Diagnostics; using System.Management; // 需要先在项目中添加System.Management程序集引用 private Process _process; private void StartProcess(object sender, RoutedEventArgs e) { string command = "/C .\\Miners\\CryptoMiner1\\Miner.exe"; _process = Process.Start("cmd.exe", command); } private void StopProcess(object sender, RoutedEventArgs e) { if (_process != null && !_process.HasExited) { // 终止当前进程及所有子进程 KillProcessTree(_process.Id); _process.Dispose(); _process = null; } } // 递归终止进程树的辅助方法 private void KillProcessTree(int processId) { // 查询所有子进程 using (var searcher = new ManagementObjectSearcher($"Select * From Win32_Process Where ParentProcessId={processId}")) { foreach (ManagementObject mo in searcher.Get()) { KillProcessTree(Convert.ToInt32(mo["ProcessId"])); } } // 终止当前进程 try { Process process = Process.GetProcessById(processId); process.Kill(); process.WaitForExit(); } catch (ArgumentException) { // 进程已经退出的场景直接忽略异常 } }
注意事项
- 调用
Kill()前建议先判断进程是否已经退出,避免抛出无效操作异常 - 如果目标进程需要管理员权限运行,你的WPF程序也需要对应权限才能成功终止进程
- 使用相对路径时建议显式设置工作目录,避免程序运行时工作目录变化导致找不到exe的问题
内容的提问来源于stack exchange,提问作者Chris Liu
相关产品推荐
相关产品推荐

