Verständnisprobleme: Standardausgabe einer Konsole lesen



  • Ich hab den folgenden Code hier gefunden: Probleme mit Pipes

    Hier ist er nochmal in ein Bisschen abgeänderter Form:

    BOOL ReadConsoleApplication(LPTSTR lpszApplication, char *lpBuffer){
        HANDLE hOutputReadTemporary = NULL;
        HANDLE hOutputRead = NULL;
        HANDLE hOutputWrite = NULL;
        HANDLE hInputWriteTemporary = NULL;
        HANDLE hInputRead = NULL;
        HANDLE hInputWrite = NULL;
        HANDLE hErrorWrite = NULL;
        SECURITY_ATTRIBUTES sa = {0};
        PROCESS_INFORMATION pi = {0};
        STARTUPINFO si = {0};
        DWORD nBytesRead = 0;
    
        sa.nLength = sizeof(SECURITY_ATTRIBUTES);
        sa.lpSecurityDescriptor = NULL;
        sa.bInheritHandle = TRUE;
    
        if(CreatePipe(&hOutputReadTemporary, &hOutputWrite, &sa, 0) == FALSE) {
            return FALSE;
        }
    
        if(DuplicateHandle(GetCurrentProcess(), hOutputWrite, GetCurrentProcess(),
            &hErrorWrite, 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE) {
            return FALSE;
        }
    
        if(CreatePipe(&hInputRead, &hInputWriteTemporary, &sa, 0) == FALSE) {
            return FALSE;
        }
    
        if(DuplicateHandle(GetCurrentProcess(), hOutputReadTemporary, GetCurrentProcess(),
            &hOutputRead, 0, FALSE, DUPLICATE_SAME_ACCESS) == FALSE) {
            return FALSE;
        }
    
        if(DuplicateHandle(GetCurrentProcess(), hInputWriteTemporary, GetCurrentProcess(),
            &hInputWrite, 0, FALSE, DUPLICATE_SAME_ACCESS) == FALSE) {  
            return FALSE;
        }
    
        if(CloseHandle(hOutputReadTemporary) == FALSE) {
            return FALSE;
        }
    
        if(CloseHandle(hInputWriteTemporary) == FALSE) {
            return FALSE;
        }
    
        si.cb = sizeof(STARTUPINFO);
        si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
        si.hStdOutput = hOutputWrite;
        si.hStdInput = hInputRead;
        si.hStdError = hErrorWrite;
        si.wShowWindow = SW_HIDE;
    
        if(CreateProcess(NULL, lpszApplication, NULL, NULL, TRUE,
            CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi) == FALSE) {
            return FALSE;
        }
    
        if(CloseHandle(pi.hThread) == FALSE) {
            return FALSE;
        }
    
        if(CloseHandle(hOutputWrite) == FALSE) {
            return FALSE;
        }
    
        if(CloseHandle(hInputRead) == FALSE) {
            return FALSE;
        }
    
        if(CloseHandle(hErrorWrite) == FALSE) {
            return FALSE;
        }
    
        while(TRUE) {
            if(ReadFile(hOutputRead, lpBuffer, 255, &nBytesRead, NULL) == FALSE) {
                if(GetLastError() == ERROR_BROKEN_PIPE) {
                    break;
                } else {
                    return FALSE;
                }
            }
    
            lpBuffer[nBytesRead] = '';
    
        }
    
        if(CloseHandle(hOutputRead) == FALSE) {
            return FALSE;
        }
    
        if(CloseHandle(hInputWrite) == FALSE) {
            return FALSE;
        }
    
        return TRUE;
    }
    

    Also, was der Code macht, ist ja:

    1. Pipe erstellen
    =>1.LeseHandle
    =>1.SchreibHandle

    ErrorHandle=1.SchreibHandle

    2.Pipe
    =>2.LeseHandle
    =>2.SchreibHandle

    hOutputRead=1.LeseHandle //Wozu muss man duplizieren, geht doch auch ohne
    hInputWrite=2.SchreibHandle //Das braucht man doch überhaupt nicht?

    Schließe: 1.LeseHandle
    Schließe: 2.SchreibHandle

    si.hStdOutput = 1.SchreibHandle //müsste Hier nicht 2. LeseHandle stehen?
    si.hStdInput = 2.LeseHandle // müsste hier nicht 1.SchreibHandle stehen?
    si.hStdError = ErrorHandle
    si.wShowWindow = SW_HIDE;
    CreateProcess(...,si,...);

    Schließe: 1.SchreibHandle
    Schließe: 2.Lesehandle
    Schließe: ErrorHandle

    ReadFile(hOutputRead...);

    Naja vielleicht verstehe ich ein paar Dinge nicht, aber das, was mich am meisten wundert, ist die Tatsache, dass es überhaupt Funktioniert. Ich dachte si würde bestimmen, welche Handles der Prozess benutzt. ReadFile benutzt doch einen ganz anderen Handle, als die, die si zugewiesen wurden. Wie funktioniert das ganze überhaupt?

    MfG

    [ Dieser Beitrag wurde am 09.07.2003 um 16:50 Uhr von JokerXXL editiert. ]



  • Hmm ein Paar Sachen habe ich inzwischen selbst rausgefunden. Was mir aber immernoch unklar ist, warum die Handles dupliziert werden müssen? Und zwar einmal als "vererbbar" und einemal nicht.

    [cpp]
    if(DuplicateHandle(GetCurrentProcess(), hOutputWrite, GetCurrentProcess(),
    &hErrorWrite, 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE) {
    return FALSE;
    }

    if(DuplicateHandle(GetCurrentProcess(), hOutputReadTemporary, GetCurrentProcess(),
    &hOutputRead, 0, FALSE, DUPLICATE_SAME_ACCESS) == FALSE) {
    return FALSE;
    }[/cpp]

    Weiß das niemand?

    MfG


Anmelden zum Antworten