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

如何从C# Windows桌面程序获取运行中Node.js进程ID并终止

问题描述

我用Visual Studio C# Windows Forms开发程序,通过以下代码可以终止tasklist中的cmd.exe进程,但从cmd.exe启动的Node.js进程仍在运行:

cmdKillerProc.txtBxStdin.Text = @"taskkill /pid " + cmdVJS3EDITOR._PID_ + @" /F";
cmdKillerProc.btnSendStdinToProcess.PerformClick();

cmdKillerProc.txtBxStdin.Text = @"taskkill /pid " + cmdVJS3WATCH._PID_ + @" /F";
cmdKillerProc.btnSendStdinToProcess.PerformClick();

cmdKillerProc.txtBxStdin.Text = @"taskkill /pid " + cmdLoader._PID_  + @" /F";
cmdKillerProc.btnSendStdinToProcess.PerformClick();

我通过以下代码获取C#进程的ID:

_PID_ = runningProcess.Id;

启动Node.js后,无论执行什么操作都无法终止它。注意:我不想使用终止所有Node.js进程的方法,且runningProcess.Kill();也无效,请问有什么解决办法?

解决办法

核心问题是Node.js进程是cmd.exe的子进程,默认情况下taskkill /pid或Process.Kill()只会终止父进程,不会递归终止子进程。可以通过以下几种方式解决:

  • 使用taskkill的/T参数递归终止子进程
    修改taskkill命令,加上/T参数,该参数会终止指定进程及其所有子进程:
cmdKillerProc.txtBxStdin.Text = @"taskkill /pid " + cmdVJS3EDITOR._PID_ + @" /F /T";
cmdKillerProc.btnSendStdinToProcess.PerformClick();

// 另外两个cmd进程同理,都添加/T参数

这个方法无需额外编写代码,直接利用系统命令的递归终止能力。

  • 在C#中手动获取并终止子进程
    如果不想依赖taskkill命令,可以通过代码遍历目标cmd进程的所有子进程并逐个终止:
// 获取指定进程的所有子进程(含递归子进程)
private static List<Process> GetChildProcesses(int parentId)
{
    List<Process> childProcesses = new List<Process>();
    foreach (Process process in Process.GetProcesses())
    {
        try
        {
            if (process.GetParentProcessId() == parentId) // .NET 5+ 可用该API
            {
                childProcesses.Add(process);
                childProcesses.AddRange(GetChildProcesses(process.Id));
            }
        }
        catch
        {
            // 跳过无权限访问的进程
            continue;
        }
    }
    return childProcesses;
}

// 使用示例:终止指定cmd进程及其所有子进程
Process cmdProcess = Process.GetProcessById(cmdVJS3EDITOR._PID_);
foreach (Process child in GetChildProcesses(cmdProcess.Id))
{
    try
    {
        child.Kill(true); // true表示强制终止
    }
    catch
    {
        continue;
    }
}
cmdProcess.Kill(true);

如果使用.NET Framework,GetParentProcessId()不可用,可通过WMI获取父进程ID:

private static int GetParentProcessId(int processId)
{
    using (ManagementObject mo = new ManagementObject($"Win32_Process.ProcessId='{processId}'"))
    {
        mo.Get();
        return Convert.ToInt32(mo["ParentProcessId"]);
    }
}

使用该方法需要添加System.Management引用。

  • 直接启动Node.js进程
    如果是通过C#启动cmd再由cmd启动Node.js,可改为直接在C#中启动Node.js进程,跳过cmd中转,这样能直接控制Node进程的生命周期:
ProcessStartInfo psi = new ProcessStartInfo("node.exe");
psi.Arguments = "你的脚本路径";
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
Process nodeProcess = Process.Start(psi);
// 保存nodeProcess.Id,后续直接调用nodeProcess.Kill(true)即可终止

这种方式最直接,避免了中间进程,精准控制目标Node进程。

内容的提问来源于stack exchange,提问作者Nikola Lukic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 09:40:26