Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

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

Geschrieben

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

Geschrieben

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]

Geschrieben

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

Geschrieben

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

Geschrieben

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.

Geschrieben

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

  • 2 Wochen später...
Geschrieben

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

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...