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.SchreibHandleErrorHandle=1.SchreibHandle
2.Pipe
=>2.LeseHandle
=>2.SchreibHandlehOutputRead=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.SchreibHandlesi.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: ErrorHandleReadFile(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