所以我一直在命名管道和匿名管道之间跳来跳去,这是我的问题。我尝试了命名管道,但它们似乎无法正常工作,所以我回到了匿名管道。但是,匿名管道需要从管道(到我没有创建的程序)读取输入,并在管道可以获得更多信息时不断读取它。这是我目前拥有的相关代码:
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。