Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Output von gepipter Konsole kann nicht ausgelesen werden (https://www.delphipraxis.net/170575-output-von-gepipter-konsole-kann-nicht-ausgelesen-werden.html)

alleinherrscher 24. Sep 2012 13:31

Output von gepipter Konsole kann nicht ausgelesen werden
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi@all.
Ich würde gerne den Output eines Konsolenprogramms in einem memo ausgeben. Bei dem Programm handelt es sich um ein Fortran Code. Das Programm führt einige Berechnungen aus und benötigt die volle Rechenkapazität eines CPU-Kerns. Wenn ich versuche, den Konsolenoutput in eine Memobox umzuleiten, funktioniert dies nicht (das memo bleibt auch nach Ende der Berechnung leer). Führe ich dagegen ein programm wie ipconfig aus, funktioniert dies problemlos. Als Code benutze ich momentan die DosCommand.pas von sirius. (angehängt). Bei anderen Ansätzen,z.B http://www.delphi-treff.de/tipps/sys...ramm-anzeigen/ friert mein Delphi Programm an der Stelle ReadFile ein.

Hat jemand eine Idee, woran dies liegen könnte?

Gruß, Michael

Namenloser 24. Sep 2012 13:43

AW: Output von gepipter Konsole kann nicht ausgelesen werden
 
Kannst/Darfst du das Fortran-Programm hier anhängen? Was passiert, wenn du das Programm in der Konsole aufrufst und die Ausgabe in eine Datei pipest? Steht was drin?

Klaus01 24. Sep 2012 13:44

AW: Output von gepipter Konsole kann nicht ausgelesen werden
 
.. schreibt das Fortran Programm auf Standard-output oder auf Error-output?

Was passiert wenn Du das Programm aus der Shell ausführst und die Ausgabe in eine Datei umleitest?


Grüße
Klaus

alleinherrscher 25. Sep 2012 10:35

AW: Output von gepipter Konsole kann nicht ausgelesen werden
 
Wenn ich die Ausgabe in eine Datei Pipe, ist diese zunächst (wenn die Rechnung läuft) leer. Am Ende der Rechnung muss das Programm mit ENTER beendet werden, was natürlich nicht geht, wenn ich das Programm in eine Datei pipe. Also habe ich CTRL+C gedrückt. Danach beinhaltet die Textdatei den gesamten Output des Programms.

Es handelt sich um ein Simulatiosprogramm für Tunnelspektroskopie auf Halbleitern: http://www.andrew.cmu.edu/user/feens...ip_v6/UniInt3/


Wenn ich das Fortran richtig verstehe, ist es der Standardoutput:

Code:
WRITE(6,*) ' '
WRITE(16,*) ' '
WRITE(6,*) 'RAD, SLOPE, ANGLE =',RAD,SLOPE,THETA
WRITE(16,*) 'RAD, SLOPE, ANGLE =',RAD,SLOPE,THETA

//edit: Okay, Write(6,*) ist der Standard Output in Fortran!

//edit2: Ich habe mal bei Sirius Quelltext folgenden Code gedebugged:

Delphi-Quellcode:
 try
        repeat //main program loop


          //thread is waiting to one of
          WaitHandles[1]:=ReadPipeThread.Event.Handle; //new output from childprocess
          WaitHandles[2]:=FInputLines.Event.Handle;   //user has new line (TDosCommand.Sendline) to deliver
          WaitHandles[3]:=FProcessInformation.hProcess; //Process-Ending (child)
          WaitHandles[4]:=FTerminateEvent.Handle; //Termination of this thread (from mainthread)
          WaitHandles[5]:=FTimer.Event.Handle; //timer elapsed (each second)

          t:=WaitforMultipleObjects(length(WaitHandles),
                                      @WaitHandles,
                                      false,
                                      infinite);
          outputdebugstring(pchar(inttostr(t)));


          case t of


            Wait_Object_0 +2 : begin //Process terminated
              GetExitCodeProcess(FProcessInformation.hProcess, FExitCode);
            end;

            Wait_Object_0+1: begin // InputEvent
              if ((FInputLines.Count > 0) and not (Terminated)) then
                DoSendLine(inputwrite,last,LineBeginned);
              if FInputLines.Count>0 then
                FInputlines.Event.SetEvent;
            end;

            Wait_Object_0 +0: begin //ReadEvent
              while ReadPipeThread.ReadString.length>0 do
                DoReadLine(ReadPipeThread.ReadString,str,last,lineBeginned);
            end;

          end;


        until Terminated or ((FExitCode <> STILL_ACTIVE) //process terminated (normally)
          or ((FMaxTimeAfterBeginning < FTimer.SinceBeginning)
          and (FMaxTimeAfterBeginning > 0)) //or time out
          or ((FMaxTimeAfterLastOutput < FTimer.SinceLastOutput)
          and (FMaxTimeAfterLastOutput > 0))); //or time out

        if (FExitCode <> Still_Active) then
        begin
          DoEndStatus(esProcess);
          FCanTerminate:=false;
        end
        else
        begin
          FCanTerminate:=true;
          if Terminated then
            DoEndStatus(esStop)
          else
            DoEndstatus(esTime);
          DoTerminateProcess; //stop Process
        end;

        if (Last <> '') then begin // If not empty flush last output
          DoLinesAdd(Last);
          if assigned(FOutputLines) then
          begin
            FSyncStr:=Last;
            if LineBeginned then
              synchronize(DoSyncOutPutLastLine)
            else
              synchronize(DoSyncOutPutAdd);
          end;
          DoNewLine(Last, otEntireLine);
        end;
      finally
        ReadPipeThread.Terminate;
        ReadPipeThread.WaitFor;
        ReadPipeThread.Free;
        if FCanTerminate then
          Waitforsingleobject(FProcessInformation.hProcess,1000);
        GetExitCodeProcess(FProcessInformation.hProcess,FExitCode);
      end;

Das Handle des Prozesses schickt offenbar kein Signal. Jedenfalls erhalte ich bis zum Ende der Rechnung immer nur t=4 , also das Signal des Timers. Aber wenn ich das Fortran Programm manuell ausführe sehe ich doch den STDOUT in einer Konsole?!?!? merkwürdig.

alleinherrscher 26. Sep 2012 09:14

AW: Output von gepipter Konsole kann nicht ausgelesen werden
 
Okay, es scheint ein generelles Problem mit dem Fortran bzw. dem GNU Fortran Compiler zu sein.

Ich habe folgende Schritte durchgeführt:

1. MinGW (GNU Fortran für Win32) installiert
2. Hello World Programm kompiliert:

Code:
       PROGRAM HELLO
       WRITE(*,*) 'Hello World'
       END
oder

Code:
       PROGRAM HELLO
       WRITE(6,*) 'Hello World'
       END
3. Code ausgeführt. In der Konsole wird jedes mal "Hello World" angezeigt, in der Pipe kommt aber nichts an.

Bin ratlos, hat jemand evtl eine Idee?

Gruß, Michael

WM_CLOSE 26. Sep 2012 09:54

AW: Output von gepipter Konsole kann nicht ausgelesen werden
 
Ich glaube es gibt noch die Möglichkeit den Konsolenpuffer auszulesen, anstatt zu pipen.
EDIT: Sieh dich mal hier um: http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:35 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz