0
因此,我一直在命名和匿名管道之間彈跳,這是我的問題。我嘗試了命名管道,他們似乎沒有爲我想要的正常工作,所以我回到匿名管道。但是,匿名管道需要從管道讀取輸入(到我沒有創建的程序),並在管道可用更多信息時不斷讀取它。這是我目前擁有的相關代碼:閱讀匿名管道不止一次保持連接打開(WinAPI)
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.
好,我設置BOOL bSuccess = ReadFile的(),並增加了以下條件:\t如果(bSuccess!) \t \t擲GetLastError函數();然而,它仍然是第一次,但第二次它永遠不會對throw語句產生影響,但程序凍結可能意味着ReadFile()被掛起。有任何想法嗎?是的,我的try {...} catch(){...}語句被正確設置爲從我的readPipe()中捕獲錯誤;功能(我測試過)。 – RageD 2010-07-13 01:15:35
我剛切換到多線程。它使這項工作按我的要求。謝謝你的幫助! – RageD 2010-07-13 04:01:35