You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Windows下cmd.exe关闭时进程终止的原因及解决方案问询

问题解析与解决方案

为什么会出现这种差异?

这本质是Windows系统中控制台会话关联进程管理机制导致的:

  • 当你在cmd.exe里启动prog1.exe时,prog1会继承cmd的控制台会话。而prog1通过boost::process::spawn启动prog2时,默认情况下prog2也会继承这个控制台会话,属于同一个控制台进程组。
  • prog1.exe退出时,它只是prog2的父进程,但Windows默认不会因为父进程终止而强制终止子进程(除非父进程通过作业对象绑定了子进程),所以prog2能继续运行。
  • 当你关闭cmd.exe时,Windows会向所有关联到该控制台会话的进程发送CTRL_CLOSE_EVENT关闭信号,绝大多数进程会响应这个信号终止运行,这就是prog2被提前终止的原因。

如何避免关闭cmd.exe时终止prog2.exe?

这里有几种可靠的解决方法,按推荐度排序:

1. 让prog2脱离控制台会话(推荐)

使用Boost.Process提供的Windows平台专属参数boost::process::windows::detach,让prog2启动时脱离原控制台,这样它就不再和cmd的控制台会话关联,关闭cmd也不会影响它:

#include <boost/process.hpp>
#include <boost/process/windows.hpp>

namespace bp = boost::process;

int main() {
    // 启动prog2并脱离控制台
    bp::spawn("prog2.exe", bp::windows::detach);
    return 0;
}

2. 不继承父进程的控制台

如果你需要更精细的控制,可以通过设置CreateProcessDETACHED_PROCESS标志(Boost.Process可以映射这个标志),让prog2不继承prog1的控制台:

bp::spawn("prog2.exe", bp::windows::create_process_args(DETACHED_PROCESS));

3. 将prog2放入独立的作业对象

你可以手动创建一个Windows作业对象,将prog2加入其中,配置作业对象不随父控制台关闭而终止进程。不过这种方法相对复杂,适合需要更高级进程管理的场景:

#include <windows.h>
#include <boost/process.hpp>

namespace bp = boost::process;

int main() {
    // 创建作业对象
    HANDLE hJob = CreateJobObject(nullptr, nullptr);
    if (hJob == nullptr) {
        // 处理错误
        return 1;
    }

    // 配置作业对象:关闭作业时不终止进程
    JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = {0};
    jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
    jeli.BasicLimitInformation.LimitFlags &= ~JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
    SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli));

    // 启动prog2并加入作业
    bp::child c("prog2.exe");
    AssignProcessToJobObject(hJob, c.native_handle());

    // 关闭作业句柄(不影响进程)
    CloseHandle(hJob);

    return 0;
}

额外说明

如果你的场景允许prog2弹出新的控制台窗口,也可以用CREATE_NEW_CONSOLE标志启动它,这样它会拥有独立的控制台,关闭原cmd也不会影响它,但这种方法会额外打开一个窗口,可能不符合需求。

内容的提问来源于stack exchange,提问作者Andrew Tomazos

火山引擎 最新活动