stronzo Geschrieben 2. März 2005 Geschrieben 2. März 2005 Hy, habe folgendes Problem. Ich möchte aus einem C Programm heraus eine Konsolenanwendung starten, welche wiederum auf Eingabe wartet und diese Verarbeitet. Die 2. Anwendung soll geöffnet gehalten werden und aus der 1 Anwendung erfolgt immer neuer Input in die 2. Anwendung. Das was das 2. Konsolenprogramm normalerweise in der dosbox ausgeben würde, durch den Input von Anwenung 1, soll jetzt in die 1. Anwendug geleitet und dort weiterverarbeitet werden. Also brauch ich Pipes ! Ist CreateProcess() da die richtige Lösung ? Kann mir da einer nen Beispielcode zeigen, an dem ich mich Orientieren kann ? Wenn es geht bitte mit vielen Kommentaren. Danke Zitieren
Klotzkopp Geschrieben 2. März 2005 Geschrieben 2. März 2005 CreateProcess ist da genau richtig. Du kannst in der STARTUPINFO-Struktur drei Handles angeben, die dann für den erzeugten Prozess STDIN, STDOUT und STDERR ersetzen. Beispielcode habe ich leider gerade nicht. Und da das nichts mit Standard-C++ zu tun hat: Verschoben nach C++: Compiler, IDEs, APIs Zitieren
stronzo Geschrieben 2. März 2005 Autor Geschrieben 2. März 2005 Upps, hast recht, hab im falschen forum gepostet. Das mit STARTUPINFO hab ich mir gedacht, hatte ich wo gelesen. Das folgende Programm startet "cmd.exe" und wartet dann bis es beendet wird. Wie kann ich die HANDLE für Stdin/Stdout/Stderr setzen ? idee für diesen code: cmd.exe soll offen gehalten werden und ich geb den Input (z.B. dir y:) in meiner anderen anwednung (welche cmd.exe gestartet hat) ein und der output (z.B: Das System kann den angegebenen Pfad nicht finden.) wird im fenster der anwendung gezeigt. #include <windows.h> #include <stdio.h> int main() { STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( π, sizeof(pi) ); // Start the child process. if( !CreateProcess( NULL, // No module name (use command line). "cmd.exe", // Command line. NULL, // Process handle not inheritable. NULL, // Thread handle not inheritable. FALSE, // Set handle inheritance to FALSE. 0, // No creation flags. NULL, // Use parent's environment block. NULL, // Use parent's starting directory. &si, // Pointer to STARTUPINFO structure. π ) // Pointer to PROCESS_INFORMATION structure. ) { printf( "CreateProcess fehlgeschlagen." ); exit(1); } DWORD dwExitCode; do { GetExitCodeProcess(pi.hProcess,&dwExitCode); } while (dwExitCode == STILL_ACTIVE); if (dwExitCode != STILL_ACTIVE) printf("beeendet"); // Close process and thread handles. CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); } [/PHP] Zitieren
stronzo Geschrieben 2. März 2005 Autor Geschrieben 2. März 2005 Hmm, habe jtzt mal versucht HANDEL auf STDOUT zu setzen. Compiler meldet keine Fehler aber es gibt einen Runtime error: 3 [main] child-test 3888 handle_exceptions: Exception: SATUS_ACCESS_VIOLATION Fogender Code: #include <stdio.h> #include <windows.h> #include <stdlib.h> void main() { char buffer[255]; // Puffer STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( π, sizeof(pi) ); // Fenster nicht sichtbar si.dwFlags=STARTF_USESHOWWINDOW; si.wShowWindow=SW_HIDE; // Ausgabe umleiten HANDLE pipe_wr,pipe_rd; CreatePipe(pipe_rd,pipe_wr,0,0); si.dwFlags|=STARTF_USESTDHANDLES; si.hStdOutput=pipe_wr; // ReadFile(pipe_rd , buffer , 123 , ... ) Bildschirm ausgaben lesen // Starte den child process. if( !CreateProcess( NULL,"cmd.exe",NULL,NULL,TRUE,CREATE_DEFAULT_ERROR_MODE,NULL,NULL,&si,π ) ) { printf("CreateProcess failed."); exit(1); } DWORD x; // Solange lesen, bis die Pipeline von der anderen Seite geschlossen wird while(ReadFile(pipe_rd,buffer,255,&x,NULL) && GetLastError() != ERROR_BROKEN_PIPE) printf("%s",buffer); // eigenes Handle schliessen CloseHandle(pipe_rd); DWORD dwExitCode; do { GetExitCodeProcess(pi.hProcess,&dwExitCode); } while (dwExitCode == STILL_ACTIVE); if (dwExitCode != STILL_ACTIVE) printf("beeendet"); // Schließe process und thread handles. CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); } [/PHP] Was hab ich falsch gemacht??? Thx Zitieren
Klotzkopp Geschrieben 3. März 2005 Geschrieben 3. März 2005 Soweit ich mich erinnere, musst du alle drei Handles angeben, sonst funktioniert das nicht. Das STDERR-Handle kannst du allerdings mit DuplicateHandle aus dem STDOUT-Handle erzeugen. Zitieren
stronzo Geschrieben 3. März 2005 Autor Geschrieben 3. März 2005 ich hab jetzt die Handles so gesetzt: HANDLE pipe_in,pipe_out; CreatePipe(pipe_in,pipe_out,0,0); si.dwFlags |= STARTF_USESTDHANDLES; si.hStdInput = pipe_in; si.hStdOutput = pipe_out; si.hStdError = pipe_out; müsste doch eigentlich reichen, oder ? bekomme trotzdem noch die selbe fehlermeldung bei laufzeit. ich brauch dringend hilfe, bzw code beispiele zu Handels und deren umgang. Möglichst in Deutsch, da mein englisch nich das beste ist. Thx Zitieren
Klotzkopp Geschrieben 3. März 2005 Geschrieben 3. März 2005 Die Handles für STDOUT und STDERR dürfen nicht gleich sein. Nimm DuplicateHandle. Außerdem dürfte es dem Prozess nicht gefallen, wenn ihm sein eigener Output wieder als Input vorgesetzt wird. Du brauchst mindestens zwei Pipes. Zitieren
stronzo Geschrieben 4. März 2005 Autor Geschrieben 4. März 2005 Ok, das mit den handles hab ich soweit hinbekommen. das prgramm nimmt den userinput entgegen und arbeitet dann die erzeigten Threads ab und beendet dann das ganze prog, funzt auch soweit. Nur ich möchte ja dass das Programme immer wieder userinput entgegennimmt ohne dass ich jedesmal das Prog neustarten muss. Also muss eine Endlosschleife her die dann in bestimmten Fällen abbricht. Hab folgende Schleife erzeugt: for(; { printf("\nBitte Enter drücken ..."); getchar(); WriteFile(hClientIn_wr,"dir",1024,&ignore,NULL); CloseHandle(hClientIn_wr); while(ReadFile(hClientOut_rd,buffer,255,&x,NULL) && GetLastError() != ERROR_BROKEN_PIPE) fwrite(buffer,x,1,stdout); fflush(stdout); CloseHandle(hClientOut_rd); } [/PHP] Jetzt wird allerdings "dir" nur einmal ausgeführt und dann wird die cmd geschlossen. Wo liegt der Fehler ? So erzeug ich den Prozess: [PHP] if(!CreateProcess(NULL,"cmd",NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS | DETACHED_PROCESS, NULL,NULL,&si,π)) { printf("Prozess erstellung fehlgeschlagen\n"); exit(5); } Ausgabe der console: D:\cygwin\home\user\child>pipe.exe Bitte Enter drücken ... << Jetzt drück ich Enter Microsoft Windows XP [Version 5.1.2600] © Copyright 1985-2001 Microsoft Corp. D:\cygwin\home\user\child>Mehr? Datenträger in Laufwerk D: ist Programme Volumeseriennummer: E46C-7E63 Verzeichnis von D:\cygwin\home\user\child 04.03.2005 10:37 <DIR> . 04.03.2005 10:37 <DIR> .. 03.03.2005 12:09 1.867 child.c 03.03.2005 12:09 14.902 child.exe 10.11.2004 14:35 1.140.617 cygwin1.dll 04.03.2005 08:46 2.262 my_shell.c 04.03.2005 08:46 16.771 my_shell.exe 04.03.2005 10:36 5.228 pipe.c 04.03.2005 10:37 17.103 pipe.exe 04.03.2005 08:39 1.503 test.c 04.03.2005 08:39 14.902 test.exe 9 Datei(en) 1.215.155 Bytes 2 Verzeichnis(se), 33.588.670.464 Bytes frei D:\cygwin\home\user\child>Mehr? << Wo kommt das Mehr? her ?? Bitte Enter drücken ... Bitte Enter drücken ... << Jetzt drücke ich wieder Enter aber nix passiert Bitte Enter drücken ... Bitte Enter drücken ... Bitte Enter drücken ... Thx Zitieren
scriptit Geschrieben 18. März 2005 Geschrieben 18. März 2005 Moin, ich habe ein ähnliches Problem... Um einen externen Prozess aus php aufrufen zu können und diese voneinander zu entkoppeln, habe ich mit CreateProzess() ein kurzes Programm gestrickt. #include <windows.h> #include <iostream> #include <string> using namespace std; int main(int argc, char* argv[]) { STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( π, sizeof(pi) ); // Start the child process. if( !CreateProcess( NULL, // No module name (use command line). "externer Prozess", // Command line. NULL, // Process handle not inheritable. NULL, // Thread handle not inheritable. FALSE, // Set handle inheritance to FALSE. 0, // No creation flags. NULL, // Use parent's environment block. NULL, // Use parent's starting directory. &si, // Pointer to STARTUPINFO structure. π ) // Pointer to PROCESS_INFORMATION structure. ) { //ErrorExit( "CreateProcess failed." ); } CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); return 0; } Bis dahin funktioniert alles super - aber ich brauche das etwas dynamischer! Jetzt würde ich das Programm gerne mit einem Übergabeparameter (string) aufrufen, der den Aufruf für den Aufzurufenden Prozess enthält... Das Array argv[] enthällt zwar alle Übergabeparameter, aber wie kann ich die in den CreateProzess() einbinden/übergeben??? Kann mir dazu jemand einen Tipp geben? Danke Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.