c++ - 如何在 Windows 中重定向 std::cout 和 printf

标签 c++ windows

我已经根据这篇文章创建了程序Creating a Child Process with Redirected Input and Output ,但它对 std::cout 和 printf 不起作用,所以从这样的程序中我得到了一个“你好,妈妈”字符串,而 cout 和 printf 部分没有任何结果:

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);

    const char *buffer = "Hello, momma";

    std::cout << buffer << " - iostream version\n";

    printf("%s - stdio version", buffer);

    DWORD dwWritten = 0;
    WriteFile(hStdOut, buffer, strlen(buffer), &dwWritten, NULL);

    return 0;
}

问: 我如何拦截 cout 和 printf? 我无权访问子程序的源代码,我只需要拦截它的输出。


如果只运行子进程,这是输出:

Hello, momma - iostream version

Hello, momma - stdio versionHello, momma

因此,如您所见,所有三个版本都已打印。


作为父程序请求的代码:

void RedirectIO(HANDLE &hRead, HANDLE &hWrite)
{
    SECURITY_ATTRIBUTES attr;
    ZeroMemory(&attr, sizeof(attr));
    attr.nLength = sizeof(attr);
    attr.bInheritHandle = true;

    CreatePipe(&hRead, &hWrite, &attr, 0);
    SetHandleInformation(hRead, HANDLE_FLAG_INHERIT, 0);
}

bool CreateChild(std::string CommandLine, DWORD WaitTime, HANDLE hInRead, HANDLE hOutWrite)
{
    STARTUPINFO SI;
    PROCESS_INFORMATION PI;
    ZeroMemory(&SI, sizeof(SI));
    ZeroMemory(&PI, sizeof(PI));

    SI.cb = sizeof(SI);
    SI.hStdError = hOutWrite;
    SI.hStdInput = hInRead;
    SI.hStdOutput = hOutWrite;
    SI.dwFlags |= STARTF_USESTDHANDLES;

    bool success = CreateProcess(0, const_cast<char*>(CommandLine.c_str()), 0, 0, true, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, 0, 0, &SI,&PI);

    if (success)
    {
        WaitForSingleObject(PI.hProcess, WaitTime);
        CloseHandle(PI.hProcess);
        CloseHandle(PI.hThread);
    }

    return success;
}

int main()
{
    HANDLE hRead = nullptr;
    HANDLE hWrite = nullptr;

    RedirectIO(hRead, hWrite);
    CreateChild("stdouterrin.exe", INFINITE, nullptr, hWrite);

    DWORD ReadCount = 0;
    char Buffer[1024] = {0};

    std::string data = std::string();

    while(true)
    {
        if (!ReadFile(hRead, Buffer, sizeof(Buffer) / sizeof(char), &ReadCount, 0))
            break;

        if (!ReadCount) break;

        Buffer[ReadCount] = '\0';
        data.append(&Buffer[0], ReadCount);
        std::cout<<"Read From Child:\n\n"<<data.c_str()<<"\n";
    }

    return 0;
}

最佳答案

您需要刷新缓冲区。

cout << flush;
fflush(stdout);

return 0; 之前

关于c++ - 如何在 Windows 中重定向 std::cout 和 printf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21191462/

相关文章:

c# - DateTime.Now 与系统时间

windows - 可以以低优先级运行 OpenCL 程序(是 "nice")?

c++ - 如何将表面对象绑定(bind)到二维倾斜阵列?

c++ - 为什么 g++ 4.9.0 默认有 std::isnan?

c++ - c std::vector 一分为二

c++ - 我如何打开这个应用程序是 visual studio 以便我可以运行代码?

c++ - 适用于 Windows 的 MPEG 4 SDK

c++ - QuantLib 多线程/并发

c++ - 我怎么能期望谷歌测试多次失败?

c++ - Qt 手势。没有收到 qgesture 事件