system("Test.exe >> test.txt"); Handle wird nicht geschlossen

cwriter

Erfahrenes Mitglied
Hallo Welt

Wie der Titel schon sagt, möchte ich die Ausgabe einer Konsolenanwendung auslesen, dies per Umleitung der Ausgabe durch die cmd.exe.
Mein Problem ist jetzt, dass die Datei zwar erstellt wird, ich sie aber nicht in Echtzeit auslesen kann, sprich der FILE* der cmd.exe nicht geschlossen wird. Einzig am Schluss der Ausführung bin ich in der Lage, den Inhalt einzusehen. Wisst ihr eine ähnlich einfache Alternative oder wie man das Problem beheben kann?

Gruss
cwriter
 
C:
system("Test.exe >> Test.txt");
Die Test.exe ist eine Win32-Konsolenapplikations und gibt Text aus, dem ich gerne mit einem WinApi einen schöneren Anstrich verpassen will. Soll heissen:
C:
system("Test.exe >> Test.txt");
Programm ist im Leerlauf.
Doppelklick auf Test.txt gibt ein leeres Editorfenster.
In laufende Konsole "quit" (Befehl zum Beenden der Test.exe) eingeben.
Doppelklick auf Test.txt zeigt die erwünschte stdout.
-------------------------------------------------------------------------
Meine Deutung:
cmd.exe schreibt öffnet FILE* auf Test.txt, schliesst ihn aber nicht fortlaufend und öffnet ihn im "a"-Mode wieder, sondern schliesst FILE* erst beim Beenden wieder.


Gruss

cwriter
 
Hi

das ist normal.
Ab einer gewissen Menge wird vermutlich was reingeschrieben, um RAM zu sparen, aber eben immer nur blockweise.

Nur mit CMD-Mitteln kannst du da nichts machen.
Du müsstest das Programm selber so umändern, dass du ihm beim Start einen Dateinamen mitgibst (argc/argv) und das Programm dann selber immer wieder öffnen/schreiben/schließen lassen.

Gruß
 
Hi
Gibt es noch eine andere Möglichkeit als das Programm zu verändern? Beispielsweise ein externes Programm, das die .exe aufruft und danach die STDOUT "hijackt"? Ich habe da mal was von pipes gelesen, werde aber daraus nicht so recht schlau. Gibt es eine Alternative zu den Pipes?

Gruss
cwriter
 
Pipes wären allerdings wirklich eine Möglichkeit.
Alternative fällt mir dazu aber keine ein.

Was ist denn das Problem mit den Pipes?
Ist vergleichbar mit einer Datei, fopen usw.
Nur ist das, was reingelesen wird, kein Dateiinhalt, sondern die Ausgabe eines anderes Konsolenprogramms.

Im externen Programm
-Das erste Programm mit popen oder so öffnen
-Eine Zeile einlesen, Datei auf, reinschreiben, Datei zu
-Nächste Zeile...
-Bis das erste Programm fertig ist, dann auch das zweite beenden

Gruß
 
Erstmal danke für deine Mühe, sheel

Mein Problem mit Pipes ist dies am Ende von http://msdn.microsoft.com/en-us/library/aa298534(v=vs.60).aspx:
Code:
Note   The _popen function returns an invalid file handle, if used in a Windows program, that will cause the program to hang indefinitely. _popen works properly in a Console application. To create a Windows application that redirects input and output, read the section "Creating a Child Process with Redirected Input and Output" in the Win32 SDK.

Ich erstelle jeweils die win32-Konsolenanwendungen. Funktioniert das denn so?

Gruss
cwriter
 
Ja, das Funktioniert.

"Windows"-Program ist etwas undeutlich, da ja nicht nur ein grafisches Programmfenster, sondern auch das Betriebssystem gemeint sein kann.
Hier ist aber die Rede von einem grafischen Fenster.

popen funktioniert nur mit dem, was aus printf und ähnlichem herauskommt.
Keine Buttons, Messageboxen etc. auf dem Bildschirm.

Gruß
 
Hallo
Erstmal danke für deine erstklassige Hilfe!
Ich habe dennoch das gleiche Problem wie mit der system() Variante.
Ich habe mal den Code der msdn geklaut:
C:
#include <stdio.h>
#include <stdlib.h>

void main( void )
{

   char   psBuffer[128];
   FILE   *f;

        /* Run DIR so that it writes its output to a pipe. Open this
    * pipe with read text attribute so that we can read it
         * like a text file.
    */
   if( (f = _popen( "MUD.exe", "rt" )) == NULL )
      exit( 1 );

   /* Read pipe until end of file. End of file indicates that
    * f closed its standard out (probably meaning it
         * terminated).
    */
    while(!feof(f))
    {
      if( fgets( psBuffer, 128, f ) != NULL )
         printf( psBuffer );
    }
   /* Close pipe and print return value of f. */
   printf( "\nProcess returned %d\n", _pclose( f ) );
   system("PAUSE");
}
Es funktioniert auch erst durch beenden! Ich verzweifle langsam echt! Siehst du hier eine Möglichkeit, STDOUT in Echtzeit auszugeben?

Gruss
cwriter
 
Hallo,

Dein Problem liegt an der Architektur von gepufferten Streams. Diese werden nicht nach jedem Zeichen geschrieben, sonder immer erst nach einer bestimmten Menge an Daten im Schreibpuffer. Oder wenn man manuell flushed, was aber voraussetzt das man das Programm welches die Ausgabe erzeugt verändern kann.
 
Zurück