Windows进程重定向输出无法工作,直到程序退出

时间:2017-02-25 13:46:53

标签: windows process

所以我在尝试重定向进程的输出时遇到了一个奇怪的问题。我创建了一个示例程序,它首先打印一个语句,然后在5秒后打印另一个语句。

我通过CreateProcesss设置我的流程,并通过CreatePipe等设置我的管道,这是所有必须做的正常事情。我确保在创建后关闭进程的OUT写入和IN rd管道。我使用PeekNamedPipe来确定是否有要读取的数据。完成所有这些初始设置之后,直到5秒钟结束后我才会收到任何输出。它只会在进程退出后向我返回数据。我似乎无法弄明白为什么。

想知道我的逻辑是否有人看错了什么?

我有以下c代码:

#include <windows.h>
#include <stdio.h>

int main(){


    // the handles for creating pipes
    HANDLE g_hChildStd_IN_Rd = NULL;
    HANDLE g_hChildStd_IN_Wr = NULL;
    HANDLE g_hChildStd_OUT_Rd = NULL;
    HANDLE g_hChildStd_OUT_Wr = NULL;
    HANDLE g_hChildStd_Err_Rd = NULL;
    HANDLE g_hChildStd_Err_Wr = NULL;

    // security attributes for inheriting pipe handles
    SECURITY_ATTRIBUTES saAttr; 

    // Set the bInheritHandle flag so pipe handles are inherited. 
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
    saAttr.bInheritHandle = TRUE; 
    saAttr.lpSecurityDescriptor = NULL; 

    // Create a pipe for the child process's STDOUT. 
    if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) ) 
        printf("StdoutRd CreatePipe"); 

    // Ensure the read handle to the pipe for STDOUT is not inherited.
    if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
        printf("Stdout SetHandleInformation"); 

    // Create a pipe for the child process's STDIN. 
    if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)) 
        printf("Stdin CreatePipe"); 

    // Ensure the write handle to the pipe for STDIN is not inherited. 
    if ( ! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) )
        printf("Stdin SetHandleInformation");


    // Create a pipe for the child process's STDERR. 
    if ( ! CreatePipe(&g_hChildStd_Err_Rd, &g_hChildStd_Err_Wr, &saAttr, 0) ) 
        printf("StdoutRd CreatePipe"); 

    // Ensure the read handle to the pipe for STDOUT is not inherited.
    if ( ! SetHandleInformation(g_hChildStd_Err_Rd, HANDLE_FLAG_INHERIT, 0) )
        printf("Stdout SetHandleInformation"); 


    STARTUPINFO si={0};

    ZeroMemory( &si, sizeof(STARTUPINFO) );
    si.cb = sizeof(STARTUPINFO); 
    si.hStdError = g_hChildStd_OUT_Wr;
    si.hStdOutput = g_hChildStd_OUT_Wr;
    si.hStdInput = g_hChildStd_IN_Rd;
    si.dwFlags |= STARTF_USESTDHANDLES;


    PROCESS_INFORMATION pi={0};
    int status = CreateProcessA("a.exe", 0, 0, 0, TRUE, 0, 0, 0, &si, &pi);
    CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    // Dont forget to close stderr once we make it. Currently stderr gets combined
    // with stdout
    CloseHandle(g_hChildStd_OUT_Wr);
    CloseHandle(g_hChildStd_IN_Rd);


    while (1 )
    {
        Sleep(200);
        DWORD dwRead = 0;
        unsigned char out[5] = {0};

        PeekNamedPipe(g_hChildStd_OUT_Rd,0,0,0,&dwRead,0);

        if (dwRead > 0) 
        {
            ReadFile(g_hChildStd_OUT_Rd,out, 5 ,&dwRead, 0);
            printf("STDOUT: %s", out);
        }

        printf("write file\n");
        WriteFile(g_hChildStd_IN_Wr,"hello\n\n",7,&dwRead,0);
    }
}

在以下程序a.exe上进行测试:

#include <stdio.h>
#include <windows.h>
int main()
{

char word[250];

printf("HELLO WORLD: ");

Sleep(500);
printf("\nyou printed %s!\n\n",word);
Sleep(5000);
printf("More prints..\n");

return 0;
}

0 个答案:

没有答案