Benutzer mit den meisten Antworten
Callback Funktion für Standardausgaben von Konsolen-Programmen?

Frage
-
Hallo Forum
Wenn ich ein Konsolen-Programm von meinem Programm aus starten will und dann aber alle Ausgaben auf die Standardausgabe selber bekommen will ... wie mache ich das?
Ich würde mir wünschen, dass ich die Standardausgabe irgendwie auf mein Programm umleiten könnte und dann mit _spawnlp (oder ähnlich) ein Konsolenprogramm aufrufen. Die Ausgabe dieses Programms sollte dann irgendwie zu mir rein kommen.
Ist so was mit vertretbarem Aufwand möglich?
Grüße
FireHeart
Antworten
-
Hier mein Vorschlag:
HANDLE hOutputRead, hOutputWrite, hErrorWrite; HANDLE hInputWrite, hInputRead; SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; ::CreatePipe(&hOutputRead, &hOutputWrite, &sa, 0); ::CreatePipe(&hInputRead, &hInputWrite, &sa, 0); ::DuplicateHandle(::GetCurrentProcess(), hOutputWrite, ::GetCurrentProcess(), &hErrorWrite, 0, TRUE, DUPLICATE_SAME_ACCESS); ::SetHandleInformation(hOutputRead, HANDLE_FLAG_INHERIT, 0); ::SetHandleInformation(hInputWrite, HANDLE_FLAG_INHERIT, 0); STARTUPINFO si; memset(&si, 0, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_USESTDHANDLES; si.hStdOutput = hOutputWrite; si.hStdInput = hInputRead; si.hStdError = hErrorWrite; // Use this if you want to hide the child: // si.wShowWindow = SW_HIDE; // Note that dwFlags must include STARTF_USESHOWWINDOW if you want to // use the wShowWindow flags. PROCESS_INFORMATION pi; // more info on http://social.msdn.microsoft.com/Forums/en-US/windowsgeneraldevelopmentissues/thread/94275f12-7fab-4dd4-b38b-d8a3047a6b5a/ wchar_t strParam[MAX_PATH]; swprintf(strParam, MAX_PATH, L"path.exe /whatever"); // exe expects its name as first param if(!::CreateProcessW(L"path.exe", strParam, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, strDirectoryPath, &si, &pi)) { // handle error -> GetLastError ::CloseHandle(hOutputWrite); ::CloseHandle(hInputRead); ::CloseHandle(hErrorWrite); ::CloseHandle(hOutputRead); ::CloseHandle(hInputWrite); return -1; } ::CloseHandle(pi.hThread); // we don't need it // close handles we passed -> now the process is responsible for closing them ::CloseHandle(hOutputWrite); ::CloseHandle(hInputRead); ::CloseHandle(hErrorWrite); // read pipe until the process terminates int iResult = 0; char strBuffer[256]; DWORD rd; while(true) { if(!ReadFile(hOutputRead, strBuffer, 256, &rd, NULL)) { if(::GetLastError() == ERROR_BROKEN_PIPE) break; // terminated else { // process terminated in an unusual way -> GetLastError iResult = -1; break; } } INT iTest = IS_TEXT_UNICODE_CONTROLS; if(::IsTextUnicode(strBuffer, rd, &iTest)) wprintf((wchar_t *)strBuffer); else printf((char *)strBuffer); } ::CloseHandle(pi.hProcess); ::CloseHandle(hOutputRead); ::CloseHandle(hInputWrite);
Rudolf
- Bearbeitet Rudolf Meier Dienstag, 20. Dezember 2016 22:28
- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Dienstag, 27. Dezember 2016 07:14
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Freitag, 6. Januar 2017 14:55
Alle Antworten
-
Hi,
C++ ist zwar nicht meine Welt, lt. MSDN geht das aber identisch wie auch bei C# und VB.NET.
https://msdn.microsoft.com/de-de/library/system.diagnostics.process.standardoutput.aspx
Dort findest Du auch ein Codebeispiel.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
- Bearbeitet Stefan Falz Mittwoch, 21. Dezember 2016 08:51
-
Hier mein Vorschlag:
HANDLE hOutputRead, hOutputWrite, hErrorWrite; HANDLE hInputWrite, hInputRead; SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; ::CreatePipe(&hOutputRead, &hOutputWrite, &sa, 0); ::CreatePipe(&hInputRead, &hInputWrite, &sa, 0); ::DuplicateHandle(::GetCurrentProcess(), hOutputWrite, ::GetCurrentProcess(), &hErrorWrite, 0, TRUE, DUPLICATE_SAME_ACCESS); ::SetHandleInformation(hOutputRead, HANDLE_FLAG_INHERIT, 0); ::SetHandleInformation(hInputWrite, HANDLE_FLAG_INHERIT, 0); STARTUPINFO si; memset(&si, 0, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_USESTDHANDLES; si.hStdOutput = hOutputWrite; si.hStdInput = hInputRead; si.hStdError = hErrorWrite; // Use this if you want to hide the child: // si.wShowWindow = SW_HIDE; // Note that dwFlags must include STARTF_USESHOWWINDOW if you want to // use the wShowWindow flags. PROCESS_INFORMATION pi; // more info on http://social.msdn.microsoft.com/Forums/en-US/windowsgeneraldevelopmentissues/thread/94275f12-7fab-4dd4-b38b-d8a3047a6b5a/ wchar_t strParam[MAX_PATH]; swprintf(strParam, MAX_PATH, L"path.exe /whatever"); // exe expects its name as first param if(!::CreateProcessW(L"path.exe", strParam, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, strDirectoryPath, &si, &pi)) { // handle error -> GetLastError ::CloseHandle(hOutputWrite); ::CloseHandle(hInputRead); ::CloseHandle(hErrorWrite); ::CloseHandle(hOutputRead); ::CloseHandle(hInputWrite); return -1; } ::CloseHandle(pi.hThread); // we don't need it // close handles we passed -> now the process is responsible for closing them ::CloseHandle(hOutputWrite); ::CloseHandle(hInputRead); ::CloseHandle(hErrorWrite); // read pipe until the process terminates int iResult = 0; char strBuffer[256]; DWORD rd; while(true) { if(!ReadFile(hOutputRead, strBuffer, 256, &rd, NULL)) { if(::GetLastError() == ERROR_BROKEN_PIPE) break; // terminated else { // process terminated in an unusual way -> GetLastError iResult = -1; break; } } INT iTest = IS_TEXT_UNICODE_CONTROLS; if(::IsTextUnicode(strBuffer, rd, &iTest)) wprintf((wchar_t *)strBuffer); else printf((char *)strBuffer); } ::CloseHandle(pi.hProcess); ::CloseHandle(hOutputRead); ::CloseHandle(hInputWrite);
Rudolf
- Bearbeitet Rudolf Meier Dienstag, 20. Dezember 2016 22:28
- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Dienstag, 27. Dezember 2016 07:14
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Freitag, 6. Januar 2017 14:55