(Gelöst)TProcess, Übergabe von Kommandos an Konsolenprogamm

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.

(Gelöst)TProcess, Übergabe von Kommandos an Konsolenprogamm

Beitragvon Frank Ranis » 7. Jul 2017, 07:06 (Gelöst)TProcess, Übergabe von Kommandos an Konsolenprogamm

Hallo ,

habe ein kleines Problem mit TProcess und der Übergabe von Steuerkommandos an ein Konsolenprogramm.

Worum geht es .

Ich benutze für meine Aerodynamikprogramme öfter mal das Konsolen-Programm XFOIL.
Hiermit kann man die Aerodynamischen Eigenschaften von Flugzeugprofilen berechnen.

Normal wird XFoil gestartet und man steuert es per Handeingaben.
Für eine Automatik per Script habe ich bis dato eine Batch-Datei und ein Sript-Textdatei verwendet.

Beispiel: Start.bat

Code: Alles auswählen
xfoil.exe < script.txt
echo XFoil ist fertig mit rechnen!! > fertig.txt


In der Datei Script.txt stehen dann die Kommandos , die das XFoil steuern .
Und am Ende fällt hinten eine Text-Tabelle mit den Berechneten Werten raus .

Das funktioniert eigentlich Problemlos , es sei denn , das XFoil gerät in ein Koma , hängt sich also weg .
Das passiert nicht sehr oft , aber ab und an doch mal und dann hat man ein Zombie am laufen , unschön.

Die Batch kann man nun auch schön per TProcess starten , funzt tadellos, es sei den XFoil stürtz ab , dann kommt man zwar an den Process heran (das Batchprogramm) aber nicht an die XFoil.exe selber , da das ja ein Prozess ist , den das Batch erzeugt hat .

Code: Alles auswählen
// Start per Batch , alte Vorgehensweise
procedure TForm1.Button1Click(Sender: TObject);
begin
 p:=tprocess.Create(nil);
 P.Options := [poWaitOnExit];
 p.Executable:=pfad+'\start.bat';
 p.Execute;
 freeandnil(p);
end;   
 

------------

Nun dachte ich mir , benutze doch einfach TProcess direct mit der XFoil.exe.
Also zunächst mal die reine XFoil.exe im Process aufgerufen.

Code: Alles auswählen
// Start der reinen XFoil.exe ohne Übergaben
procedure TForm1.Button2Click(Sender: TObject);
begin
 p:=tprocess.Create(nil);
 P.Options := [poWaitOnExit];
 p.Executable:=pfad+'\xfoil.exe';
 p.Execute;
 freeandnil(p);
end;         
 

Funzt , XFoil-Prog wird aufgemacht und ich kann dort meine Kommandos per Hand eingeben (z.B. Quit+Enter zum Verlassen des XFoil).

------------

Diese Procedure dann erweitert mit der Möglichkeit , Textkommados zu übergeben.

Code: Alles auswählen
// Versuch mit Kommando-Übergabe
procedure TForm1.Button3Click(Sender: TObject);
var s:string;
begin
 p:=tprocess.Create(nil);
 P.Options := [poUsePipes];
 p.Executable:=pfad+'\xfoil.exe';
 p.Execute;
 
 // Ab hier sollen dann die Kommandos (siehe Script.txt) gesendet werden
 s:='load NACA4415.DAT';
 p.Input.Write(s,length(s));
 
 sleep(2000);
 
 freeandnil(p);
end;       


Aber nun startet das XFoil nicht mehr .

Klammere ich die Zeile

Code: Alles auswählen
P.Options := [poUsePipes];


aus , wird XFoil zwar ausgeführt , dafür ballert es dann in der Zeile

Code: Alles auswählen
p.Input.Write(s,length(s));



Hat irgend jemand eine Idee , wie man das zum Laufen bekommen kann ?

Der komplette Code im Anhang.

Gruß

Frank
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Zuletzt geändert von Frank Ranis am 7. Jul 2017, 13:26, insgesamt 1-mal geändert.
www.flz-vortex.de
Frank Ranis
 
Beiträge: 80
Registriert: 24. Jan 2013, 21:22
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z) | 
CPU-Target: xxBit
Nach oben

Beitragvon Socke » 7. Jul 2017, 08:11 Re: TProcess, Problem mit Übergabe von Kommandos an Konsolen

Hast du versucht, poWaitOnExit und poUsePipes miteinander zu kombinieren?
Edit: der Vorschlag kann nicht funktionieren, da dein Programm darauf wartet, dass der Prozess fertig ist, bevor es Daten sendet.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Socke
 
Beiträge: 2387
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 8.1/Debian GNU/Linux/Raspbian | 
CPU-Target: 32bit x86 armhf
Nach oben

Beitragvon Frank Ranis » 7. Jul 2017, 08:44 Re: TProcess, Problem mit Übergabe von Kommandos an Konsolen

Hi Socke,

Socke hat geschrieben:Hast du versucht, poWaitOnExit und poUsePipes miteinander zu kombinieren?
Edit: der Vorschlag kann nicht funktionieren, da dein Programm darauf wartet, dass der Prozess fertig ist, bevor es Daten sendet.


Nein , in Procedure Button3Click ist die Option 'poWaitOnExit' nicht enthalten.

Gruß

Frank
www.flz-vortex.de
Frank Ranis
 
Beiträge: 80
Registriert: 24. Jan 2013, 21:22
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z) | 
CPU-Target: xxBit
Nach oben

Beitragvon Warf » 7. Jul 2017, 11:44 Re: TProcess, Problem mit Übergabe von Kommandos an Konsolen

Mal so ne ganz dumme Anmerkung, mit
Code: Alles auswählen
s:='load NACA4415.DAT';
 p.Input.Write(s,length(s));

sendest du keinen Newline Character. Wenn das Programm die Informationen Zeile für Zeile einliest, wird es sowiso so lange blockieren bis du einen newline Character schreibst. Also mich würde es definitiv nicht wundern falls du damit einen Deadlock erhälst
Warf
 
Beiträge: 616
Registriert: 23. Sep 2014, 16:46
Wohnort: Aachen
OS, Lazarus, FPC: Mac OSX 10.11 | Win 10 | FPC 3.0.0 | L trunk | 
CPU-Target: x86_64, i368, ARM
Nach oben

Beitragvon Socke » 7. Jul 2017, 12:05 Re: TProcess, Problem mit Übergabe von Kommandos an Konsolen

Jetzt ist mir der Fehler aufgefallen. Die Variable s ist technisch nur ein Pointer auf den String; mit deinem Code schreibst du nur den Pointer und das was danach kommt.
Stattdessen musst du das erste Zeichen aus dem String angeben:
Code: Alles auswählen
s:='load NACA4415.DAT';
 p.Input.Write(s[1],length(s));
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Socke
 
Beiträge: 2387
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 8.1/Debian GNU/Linux/Raspbian | 
CPU-Target: 32bit x86 armhf
Nach oben

Beitragvon Frank Ranis » 7. Jul 2017, 13:20 Problem gelöst

Hallo Socke,

Socke hat geschrieben:Jetzt ist mir der Fehler aufgefallen. Die Variable s ist technisch nur ein Pointer auf den String; mit deinem Code schreibst du nur den Pointer und das was danach kommt.
Stattdessen musst du das erste Zeichen aus dem String angeben:
Code: Alles auswählen
s:='load NACA4415.DAT';
 p.Input.Write(s[1],length(s));


Ja , habe ich auch entdeckt , danke für den Hinweis.

Habe jetzt folgendes herausgefunden:

Benutzt man die
Code: Alles auswählen
P.Options := [poUsePipes] 

wird sämtliche Ein/Ausgabe in die Konsole vom Prozess abgefangen.

Und weil da keine Anzeige kam , hat mich das stutzig gemacht.

Man muß sich die Informationen halt selber holen .
Somit ist auch eine Anzeige der Konsole unnütz und man kann diese gleich mit abschalten.
Also
Code: Alles auswählen
P.Options := [poUsePipes,poNoConsole]; 


Im Anhang noch das funktionierende Projekt , wenn es jemanden interessiert.

Muß nur noch alles in einen separten Thread packen , damit das Hauptprogramm aktiv bleibt .

Ich danke euch trotzdem .

Gruß

Frank
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
www.flz-vortex.de
Frank Ranis
 
Beiträge: 80
Registriert: 24. Jan 2013, 21:22
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z) | 
CPU-Target: xxBit
Nach oben

Beitragvon braunbär » 8. Jul 2017, 10:42 Re: (Gelöst)TProcess, Übergabe von Kommandos an Konsolenprog

Ein Hinweis zu deinem Programm:

Code: Alles auswählen
procedure TForm1.FormCreate(Sender: TObject);
begin
 pfad:=extractfiledir(paramstr(0));
end;
 



Lazarus-Hilfe hat geschrieben:In general, it's a bad idea to rely on the location of the binary. Often, this goes against best OS practices. Configuration data should (or can) not be stored next to the binary, but on designated locations. What locations these are, is very much operating system dependent. Therefore, ParamStr(0) should be used with care.


FAst immer ist es m.E. besser, GetCurrentDir zu verwenden. Das liefert dir das aktuelle Arbeitsverzeichnis, unabhängig davon, aus welchem Verzeichnis das Programm gestartet wurde. Wenn man eine Programmverknüpfung erstellt, ist das Arbeitsverzeichnis ohnedies standardmäßig das Programmverzeichis, aber das kann man in der Verknüpfung eben ändern, wenn man will. Normalerweise ist es für das laufende Programm egal, in welchem Verzeichnis das Exe-File steht (außer, man will - unter Windows - eine DLL aus dem Programmverzeichnis laden, oder dergleichen), wichtig ist, wenn schon, das Arbeitsverzeichnis.
braunbär
 
Beiträge: 164
Registriert: 8. Jun 2017, 17:21

Beitragvon m.fuchs » 8. Jul 2017, 11:38 Re: (Gelöst)TProcess, Übergabe von Kommandos an Konsolenprog

braunbär hat geschrieben:
Code: Alles auswählen
 pfad:=extractfiledir(paramstr(0))


FAst immer ist es m.E. besser, GetCurrentDir zu verwenden. Das liefert dir das aktuelle Arbeitsverzeichnis, unabhängig davon, aus welchem Verzeichnis das Programm gestartet wurde.

Das nützt dem OP aber gar nichts, schadet nur. Er geht ja davon aus dass xfoil.exe im gleichen Verzeichnis wie sein eigenes Programm liegt. Dafür braucht er den Pfad. Benutzt er nun GetCurrentDir und das Programm wird aus einem anderen Verzeichnis gestartet, dann wird xfoil.exe nicht mehr gefunden.

ParamStr(0) und GetCurrentDir sind nicht synonym.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
m.fuchs
 
Beiträge: 1676
Registriert: 22. Sep 2006, 18:32
Wohnort: Berlin
OS, Lazarus, FPC: Winux (L 1.6, FPC 3.0) | 
CPU-Target: x86, x64, arm
Nach oben

Beitragvon braunbär » 8. Jul 2017, 13:43 Re: (Gelöst)TProcess, Übergabe von Kommandos an Konsolenprog

Ja, du hast Recht. Mir ist das paramStr(0) ins Auge gesprungen, was man normalerweise bleiben lassen (oder zumindest einen kurzen erklärenden Kommentar dazu schreiben) sollte, genauer habe ich mir dann nicht angeschaut, was das Programm damit macht.

Dein belehrendes "ParamStr(0) und GetCurrentDir sind nicht synonym." hättest du dir allerdings sparen können, weil wenn die synonym wären, dann wäre mein Kommentar sowieso obsolet.
braunbär
 
Beiträge: 164
Registriert: 8. Jun 2017, 17:21

Beitragvon wp_xyz » 8. Jul 2017, 14:39 Re: (Gelöst)TProcess, Übergabe von Kommandos an Konsolenprog

braunbär hat geschrieben:Dein belehrendes "ParamStr(0) und GetCurrentDir sind nicht synonym." hättest du dir allerdings sparen können...

Nicht schon wieder! Jeder, der hier etwas antwortet, ist irgendwie "belehrend". Bitte spare dir solche stichelnde Attribute.
wp_xyz
 
Beiträge: 2251
Registriert: 8. Apr 2011, 08:01

• Themenende •

Zurück zu Sonstiges



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste

porpoises-institution
accuracy-worried