编辑:我将仅将system
与std::filesystem::path
一起使用,因为它可移植且非常简单。由于我的程序可能不需要任何管理员权限,因此我相信这不会以麻烦而告终。
经过大量研究和大量尝试,我发现了如何直接从C ++启动另一个程序。不幸的是,有很多不同的方法可以执行此操作,例如,丑陋的system
,旧posix spawn
和特定于平台的WinAPI。
我真的很想让我的可执行文件尽可能地可移植。由于缺乏安全性,我无法使用system
,可以吗? WinAPI仅可在Windows上运行,但我最喜欢的spawn
一堆功能也不起作用,至少在Windows 10下无法响应。
那么从C ++运行程序的最好,最便携的方法是什么?有一个多功能的功能吗?还是应该运行预处理程序并检查Win-OS或Non-Win-OS?
欢迎使用任何代码段!
答案 0 :(得分:2)
启动其他可执行文件的最便捷的方式
C ++标准库只有std::system
,which:
使用参数command调用主机环境的命令处理器(例如/bin/sh、cmd.exe、command.com)。返回实现定义的值(通常是被调用程序返回的值)。
它在所有符合标准的系统上都可用,但是shell语法将由实现定义。只需使用可执行文件的路径即可移植。
但是它有潜在的缺点:
POSIX标准指定exec
which is:
exec系列功能应将当前过程映像替换为新的过程映像。
这是一个较低级的函数,可以像system
一样使用,但是如果需要,您需要自己创建一个子流程。
但是并非所有操作系统都支持POSIX标准,尤其是Windows并不支持。 Windows显然在其POSIX兼容性层中有_execv
(请注意POSIX函数以下划线作为前缀),但是它有一个局限性:
此API不能在Windows运行时中执行的应用程序中使用。
此外,如果您希望产生一个子流程并保持原始流程运行,则没有标准的方法可以在标准C ++中创建子流程。
POSIX指定fork
(和spawn
,它们结合了fork
和exec
)。 Windows有自己的API。
因此,鉴于缺乏通用标准,可移植地启动另一个可执行文件(可能在子进程中)的方法是使用预定义的宏来检测目标系统,并针对所需的每个API分别实现功能支持。
如果没有缺点,请使用std::system
。
答案 1 :(得分:1)
以自己的便携式方式进行操作:
#include <cstdlib>
#include <iostream>
#include <string_view>
#include <thread>
auto mysystem(const std::string_view cmdline, bool detach = false) {
std::thread retval = std::thread([cmdline] { std::system(cmdline.data()); });
if(detach) retval.detach();
return retval;
}
int main() {
auto t = mysystem("find /");
t.join();
// or
mysystem("find /", true); // to detach the thread and therefore process
}