在Windows上执行进程并获取结果

Execute process and get result on Windows

本文关键字:获取 结果 进程 执行 Windows      更新时间:2023-10-16

我有一段代码,它执行一个过程并检索结果。

namespace {
    FILE* really_popen(const char* cmd, const char* mode) {
#ifdef _MSC_VER
        return _popen(cmd, mode);
#else
        return popen(cmd, mode);
#endif
    }
    void really_pclose(FILE* pipe) {
#ifdef _MSC_VER
        _pclose(pipe);
#else
        pclose(pipe);
#endif
    }
    std::string ExecuteProcess(std::string cmd) {
        FILE* pipe = really_popen(cmd.c_str(), "r");
        if (!pipe) throw std::runtime_error("Could not invoke command " + cmd);
        char buffer[128];
        std::string result = "";
        while(!feof(pipe)) {
            if(fgets(buffer, 128, pipe) != NULL)
                result += buffer;
        }
        really_pclose(pipe);
        return result;
    }
}

这在Linux上对我来说很好,但在Windows上,它有一个可怕的死锁习惯——似乎fgets永远不会返回。我已经研究了CRT源,fgets最终委托给ReadFile,它永远不会返回。

如果我从命令行调用该命令,它会在一秒钟内返回。

如何在不使父级死锁的情况下读取Windows上的输出?

如果子级尚未退出,那么对fgets((的调用将不会退出,因此需要解决子级未退出的原因。在这种情况下,最有可能的原因是孩子挂断了,因为它没有标准的输入。

如果是这个问题,您可以通过将管道模式更改为"rw"来解决它。你通常不需要用额外的管道做任何事情,它只需要在那里。

(正如您在评论中提到的,这个问题也可以通过使用命令shell重定向来解决,为子级提供NUL的句柄作为标准输入。(