2010-07-12 33 views
0

因此,我一直在命名和匿名管道之間彈跳,這是我的問題。我嘗試了命名管道,他們似乎沒有爲我想要的正常工作,所以我回到匿名管道。但是,匿名管道需要從管道讀取輸入(到我沒有創建的程序),並在管道可用更多信息時不斷讀取它。這是我目前擁有的相關代碼:閱讀匿名管道不止一次保持連接打開(Win​​API)

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.

回答

0

這是不可能的猜測爲什麼,如果你不找出失敗的原因。 ReadFile在失敗時返回FALSE。然後您應該調用GetLastError()來獲取診斷。

永遠不要忽略Windows API返回值。至少斷言他們。

+0

好,我設置BOOL bSuccess = ReadFile的(),並增加了以下條件:\t如果(bSuccess!) \t \t擲GetLastError函數();然而,它仍然是第一次,但第二次它永遠不會對throw語句產生影響,但程序凍結可能意味着ReadFile()被掛起。有任何想法嗎?是的,我的try {...} catch(){...}語句被正確設置爲從我的readPipe()中捕獲錯誤;功能(我測試過)。 – RageD 2010-07-13 01:15:35

+0

我剛切換到多線程。它使這項工作按我的要求。謝謝你的幫助! – RageD 2010-07-13 04:01:35