system()最快但最不安全,适合调试;createprocess()精确控制启动行为但需手动管理句柄;c++标准库目前无跨平台进程api;shellexecuteex()不适用于自动化调用。

用 system() 最快但最不安全
直接执行命令行字符串,适合调试或临时调用,比如 system("notepad.exe")。它会阻塞当前线程,直到外部程序退出;返回值是子进程的退出码(注意:Windows 下可能被壳层截断,system() 自身失败时返回 -1)。问题在于无法控制工作目录、无法捕获输出、不能设置超时,且容易被注入攻击——如果参数来自用户输入,拼接字符串极危险,比如 system(("start " + filename).c_str()) 遇到含空格或分号的 filename 就会出错甚至执行意外命令。
用 CreateProcess() 精确控制启动行为(Windows)
这是 Windows 原生方式,能指定工作路径、环境变量、是否隐藏窗口、标准句柄重定向等。关键点:STARTUPINFO 必须初始化为 0(用 ZeroMemory(&si, sizeof(si))),si.cb = sizeof(si) 忘设会导致崩溃;CREATE_NO_WINDOW 仅对控制台程序有效,GUI 程序仍可能闪现;若需读取子进程输出,必须先创建管道(CreatePipe),再把 hStdOutput 设为写端句柄,并设 si.dwFlags |= STARTF_USESTDHANDLES。常见错误是没关闭继承句柄,导致子进程卡住父进程的管道读端。
用 std::process::Command(C++26 草案,暂不可用)?别信
目前 C++ 标准库(C++20/23)**没有**跨平台进程管理 API。std::process::Command 是提案编号 P1165,尚未进入任何正式标准,所有声称“C++23 支持 Command”的文章都混淆了 Rust 或 Boost.Process。实际项目中,跨平台方案只有两个选择:自己封装 CreateProcess()(Windows)+ fork()/exec()(Linux/macOS),或引入 Boost.Process。后者接口清晰,支持异步等待、信号中断、流重定向,但会增加构建依赖和二进制体积。
为什么 ShellExecuteEx() 不推荐用于自动化调用
它适合“打开文档”这类用户意图操作(如双击 .txt 文件触发关联程序),但不返回进程句柄,无法等待结束、无法获取退出码、无法强制静默。参数 SEE_MASK_NOCLOSEPROCESS 看似能拿到 hProcess,但仅对直接可执行文件有效,对文档类型(如 .pdf)会返回关联阅读器的句柄,且该句柄可能早已被系统回收。调试时看到 WaitForSingleObject 返回 WAIT_FAILED 或 INVALID_HANDLE_VALUE,大概率就是误用了这个 API。
真正难的不是启动,是处理子进程生命周期:怎么判断它卡死、怎么清理残留句柄、怎么安全读取乱码输出(尤其中文路径下的 CMD 输出)、怎么在异常退出时保证资源释放。这些细节在 system() 里全被掩盖了,而一旦业务逻辑变复杂,绕不开 CreateProcess() 的手动管理。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











