2010-07-12 3 views
0

Donc je continue de rebondir entre les tuyaux nommés et anonymes et voici mon problème. J'ai essayé des tubes nommés et ils ne semblaient pas fonctionner correctement pour ce que je voulais, donc je suis de retour à des pipes anonymes. Toutefois, le canal anonyme doit lire les entrées d'un canal (vers un programme que je n'ai pas créé) et le lire en continu car plus d'informations sont disponibles sur le canal. Voici le code correspondant que j'ai actuellement:Lire des tuyaux anonymes plus d'une fois tout en gardant la connexion ouverte (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();"; 
} 

Et voici comment je lis le tuyau:

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 est défini à 0x1000 et outStd est défini comme PIPE_HANDLES (struct ci-dessous)

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; 

Maintenant, je peux appeler correctement readPipe(); une fois et il fait exactement ce que je veux. Cependant, si j'essaie de l'appeler à nouveau, cela échoue. Des idées sur comment je peux résoudre ce problème? Comme je l'ai dit, je dois garder la connexion ouverte et lire progressivement. Par souci d'argument, dis que j'ai besoin de lire toutes les 5 secondes; le programme que je suis en train de lire aura une sortie différente toutes les 5 secondes qui doit être lue. De l'aide?

Cordialement,
Dennis M.

Répondre

0

Il est impossible de deviner pourquoi il échoue si vous ne trouvez pas pourquoi. ReadFile renvoie FALSE en cas d'échec. Vous devriez alors appeler GetLastError() pour obtenir un diagnostic.

N'ignorez jamais les valeurs de retour de l'API Windows. À tout le moins les affirmer.

+0

ok je mis BOOL bSuccess = ReadFile() et ajouté la condition suivante: si \t (bSuccess!) \t \t jet GetLastError(); Cependant, il fonctionne toujours la première fois, mais la deuxième fois, il ne parvient jamais à l'instruction throw, mais le programme se bloque, ce qui signifie que ReadFile() est suspendu. Des idées? Et oui, mon instruction {...} catch() {...} est correctement configurée pour intercepter les erreurs de mon readPipe(); fonction (j'ai testé). – RageD

+0

Je viens de passer au multi-threading. Il fait ce travail comme j'ai besoin. Merci de votre aide! – RageD

Questions connexes