Windows中的二进制管道

时间:2017-04-17 15:33:37

标签: windows visual-c++ pipe

我能够创建子进程并管道其stdin和stdout。它在文本模式下工作正常。 但是,当我尝试将子进程中的I / O设置为二进制格式(即没有0​​x0A到0x0D 0x0A转换)时,子进程失败。 _setmode返回-1,已记录为表示失败。为什么会这样,以及如何解决?

父代码类似于以下内容:

const std::string path;  // = "path_to.exe"
PROCESS_INFORMATION info;
SECURITY_ATTRIBUTES sec_attr;

//in-out from the CHILD process' perspective
HANDLE out_r = nullptr;
HANDLE out_w = nullptr;
HANDLE in_r = nullptr;
HANDLE in_w = nullptr;


sec_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
sec_attr.lpSecurityDescriptor = NULL;
sec_attr.bInheritHandle = TRUE; //inherit by child processes

if (!CreatePipe(&out_r, &out_w, &sec_attr, 0))
    throw std::exception();
if (!SetHandleInformation(out_r, HANDLE_FLAG_INHERIT, 0))
    throw std::exception();

if (!CreatePipe(&in_r, &in_w, &sec_attr, 0))
    throw std::exception();
if (!SetHandleInformation(in_r, HANDLE_FLAG_INHERIT, 0))
    throw std::exception();

if (out_r && out_w && in_r && in_w)
{
  startup_info.hStdError = out_w;
  startup_info.hStdOutput = out_w;
  startup_info.hStdInput = in_r;
  startup_info.dwFlags = STARTF_USESTDHANDLES;
}

if (CreateProcessA(path.c_str(), (char*)cmd, NULL, NULL, TRUE, 0, NULL, NULL, &startup_info, &info)
    != TRUE)
{
    DWORD error = GetLastError();
    //error handling
}

// ... read data using ReadFile

子代码类似于以下内容:

int status = _setmode(_fileno(stdin), _O_BINARY);
if (status == -1)
    throw std::exception();

status = _setmode(_fileno(stdout), _O_BINARY);
if (status == -1)
    throw std::exception();

puts("hello from the child process");

1 个答案:

答案 0 :(得分:2)

我正在查看MSDN文章Creating a Child Process with Redirected Input and Output,该文章几乎提供​​了您在此处尝试做的参考实现。

我看到的一个细微差别是,在父代码中写入的位置(第二次调用SetHandleInformation()):

if (!SetHandleInformation(in_r, HANDLE_FLAG_INHERIT, 0))

将编写MSDN示例(翻译为使用您的变量名称):

if (!SetHandleInformation(in_w, HANDLE_FLAG_INHERIT, 0))

如果这个小小的改变无济于事,那么还有一些SO页面值得关注: