You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 14:09:03