Читайте анонимные каналы более одного раза, оставляя соединение открытым (WinAPI) - PullRequest
0 голосов
/ 12 июля 2010

Так что я продолжаю подпрыгивать между именованными и анонимными каналами, и вот моя проблема.Я попробовал именованные каналы, и они просто не работали должным образом для того, что я хотел, поэтому я вернулся к анонимным каналам.Тем не менее, анонимный канал должен читать входные данные из канала (в программу, которую я не создавал) и непрерывно читать его, поскольку для канала доступна дополнительная информация.Вот соответствующий код, который у меня есть на данный момент:

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 секунд выводить разные данные, которые необходимо прочитать.Любая помощь?

С уважением,Деннис М.

1 Ответ

0 голосов
/ 12 июля 2010

Невозможно угадать, почему это не получается, если вы не выясните, почему.ReadFile возвращает FALSE в случае сбоя.Затем вы должны вызвать GetLastError () для получения диагностики.

Никогда не игнорируйте возвращаемые значения Windows API.По крайней мере, отстаивать их.

...