在保持连接打开的同时不止一次读取匿名管道(WinAPI)

时间:2010-07-12 17:31:59

标签: c++ winapi io pipe readfile

所以我一直在命名和匿名管道之间蹦蹦跳跳,这是我的问题。我试过命名管道,他们似乎没有正常工作我想要的,所以我回到匿名管道。但是,匿名管道需要从管道读取输入(到我没有创建的程序),并且随着管道可用的更多信息不断读取它。以下是我目前的相关代码:

void Arc_Redirect::createProcesses()
{
    TCHAR programName[]=TEXT("program.exe");
    PROCESS_INFORMATION pi; 
    STARTUPINFO si;

    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;

    if(!CreatePipe(&outStd[0].hOutRead,&outStd[0].hOutWrite,&sa,0) || !CreatePipe(&outStd[0].hInRead,&outStd[0].hInWrite,&sa,0))
        throw "Error: Could not CreatePipe();!";

    if(!SetHandleInformation(outStd[0].hOutRead,HANDLE_FLAG_INHERIT,0) || !SetHandleInformation(outStd[0].hInWrite,HANDLE_FLAG_INHERIT,0))
        throw "Error: Could not SetHandleInformation();";


    // Set stuff up
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO); 
    si.hStdError = outStd[0].hOutWrite;
    si.hStdOutput = outStd[0].hOutWrite;
    si.hStdInput = outStd[0].hInRead;
    si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;

    outStd[0].o1.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

    if(!CreateProcess(programName,NULL,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi))
        throw "Error: Could not start Program!";

    // Cleanup the useless handles
    if(!CloseHandle(pi.hThread) || !CloseHandle(pi.hProcess))
        throw "Error: Could not CloseHandle();";
}

这就是我在阅读管道的方式:

void Arc_Redirect::readPipe()
{
    CHAR chBuf[BUFSIZE];
    DWORD dwRead;

    ReadFile(outStd[0].hOutRead,chBuf,sizeof(chBuf),&dwRead,&outStd[0].o1);
    chBuf[dwRead] = '\0';
    SetDlgItemText(global,IDO_WORLDOUT,chBuf);
    ResetEvent(outStd[0].o1.hEvent);

}

BUFSIZE定义为0x1000,outStd定义为PIPE_HANDLES(下面的结构)

typedef struct
{
    HANDLE hOutRead;
    HANDLE hOutWrite;
    HANDLE hInRead;
    HANDLE hInWrite;
    OVERLAPPED o1;
    TCHAR chReq[BUFSIZE];
    TCHAR chReply[BUFSIZE];
    DWORD dwRead;
    DWORD dwWritten;
    DWORD dwState;
    DWORD cbRet;
    BOOL pendingIO;
} PIPE_HANDLES, *LPSTDPIPE;

现在,我可以正确调用readPipe();曾经,它完全符合我的要求。但是,如果我再试一次,它就会失败。关于如何解决这个问题的任何想法?就像我说的,我需要保持连接打开并逐步读取。为了争论,我说我需要每5秒读一次;我正在阅读的程序每5秒钟会有不同的输出需要读取。有什么帮助吗?

的问候,
丹尼斯M。

1 个答案:

答案 0 :(得分:0)

如果你没有找到原因,就不可能猜到它失败的原因。 ReadFile失败时返回FALSE。然后,您应该调用GetLastError()来获取诊断信息。

永远不要忽略Windows API返回值。至少断言他们。