Frage zu Sysutils.ExecuteProcess

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
pjensen
Beiträge: 77
Registriert: Fr 27. Jul 2007, 08:43
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Nahe Flensburg

Frage zu Sysutils.ExecuteProcess

Beitrag von pjensen »

Hallo,

Suse Linux 11.0 (KDE) , fpc 2.2.4 und Lazarus 0.9.29beta.
Vorhanden sind: Das Buch Free Pascal 2 und die Reference Guide (pdf).

Die Function Sysutils.ExecuteProcess(...) führt angeblich einen shell-Befehl aus und gibt ein Ergbnis als Integer zurück.
(Bei Erfolg eine 0)

Ich möchte mit Hilfe von OpenOffice ein paar Writer-Dateien in pdf wandeln.
Danach möchte aus diesen PDF-Dateien mit Hilfe von "pdftk" eine "Gesamt-PDF-Datei" erzeugen (mergen).

So sieht in etwa die Geschichte aus:

Code: Alles auswählen

if Sysutils.ExecuteProcess(soffice,' -headless -pt PDF-Konverter '+OOO_Files) = 0 then
  Begin
//    delay(2000);
    ErgFile:='Test';
    Merge_PDF(PDF_Files,ErgFile);
    Sysutils.ExecuteProcess('/opt/kde3/bin/kpdf',ErgFile);
end;
(soffice ist ein String zu meiner OpenOffice.BIN-Datei)

Das Umwandeln einiger PDF-Dateien mittels OpenOffice benötigt heribei Zeit, ca. 500ms pro Seite.

Der o.g. Code funktioniert nicht, weil die 0 geliefert wird, bevor OpenOffice mit dem Umwandeln fertig ist.
Da zu diesem Zeitpunkt aber nicht unbedingt alle PDF-Dateien schon existieren, stirbt die Prozedure Merge_PDF eines unnatürlichen Todes, weil sie einige der PDF-Dateien nicht findet, da diese zu diemsem Zeitpunkt noch nicht existieren.

Wenn ich das Delay(2000) auskommentiere, funktioniert es dann. Ich könnte also sinngenmäß schreiben: Delay ca. 500ms pro Datei.
Je mehr Seiten ich umwandele , um so höher muss der Delay-Wert sein.

Frage: Warum kommt die 0 von "Sysutils.ExecuteProcess(soffice,' -headless -pt PDF-Konverter '+OOO_Files) = 0" zu früh?
bzw. wieso fängt die Merge-Geschichte an, bevor OpenOffice fertig ist?

Frage: Gibt es bessere Lösungen als Delay?

Mfg, P. Jensen

_X_
Beiträge: 250
Registriert: Di 16. Dez 2008, 20:13
OS, Lazarus, FPC: aptosid (aptosid.com); Lazarus SVN gtk2+qt4; FPC 2.4.0
CPU-Target: 32/64Bit

Re: Frage zu Sysutils.ExecuteProcess

Beitrag von _X_ »

Versuch es mal mit TProcess.
Dazu gibts in der Lazarus-Wiki einige Beispiele.

mfg _X_

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Frage zu Sysutils.ExecuteProcess

Beitrag von mse »

pjensen hat geschrieben: Die Function Sysutils.ExecuteProcess(...) führt angeblich einen shell-Befehl aus und gibt ein Ergbnis als Integer zurück.
ExecuteProcess führt das Program direkt aus ohne Benutzung der shell AFAIK. Dies erklärt aber nicht das seltsame Verhalten.
Erzeugt OpenOffice zur pdf Umwandlung vielleicht child-Prozesse oder übergibt die Arbeit einem server-Prozess?
Es gab einmal das umgekehrte Problem:
http://qa.openoffice.org/issues/long_li ... ist=107827

pjensen
Beiträge: 77
Registriert: Fr 27. Jul 2007, 08:43
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Nahe Flensburg

Re: Frage zu Sysutils.ExecuteProcess

Beitrag von pjensen »

Q MSE:

Ich hatte mal sinngemäß folgendes gemacht:

Code: Alles auswählen

Memo1.clear;
Erg := Sysutils.ExecuteProcess(soffice,' -headless -pt PDF-Konverter '+OOO_Files)
showstring (IntToStr(Erg));      
// Showstring = memo1.addlines...
Die folgende Mergeschleife hatte ich dabei komplett auskommentiert.

Wenn ich dann per Button die Prozedure mit OpenOffice aufrufe, dauert es einen kleinen Moment, bis das Ergebnis (also die 0) angezeigt wird.
Die Zeit kann ich nicht messen, aber gefühlt entspricht die Zeit bis showstring die 0 anzeigt der Zeit, die OpenOffice zum Erstellen der PDF-Dateien benötigt.

Ich würde jetzt davon ausgehen, dass die folgende "Merge-Schleife" darauf wartet, dass Sysutils.ExecuteProcess... (bei Erfolg) die 0 liefert und erst danach los legt. Blöderweise legt sie scheinbar sofort los...

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

Eben nochmal ausprobiert:
Die Mergeschleife nicht auskommentiert, und

Code: Alles auswählen

if Sysutils.ExecuteProcess(soffice,' -headless -pt PDF-Konverter '+OOO_Files) = 1 then
geschrieben. (Man beachte die 1 am Ende)
Da eine 0 geliefert wird, die Merge-Schleife jetzt aber nur bei Lierferung einer 1 starten soll, wird sie nicht gestartet.

Offensichtlich wird in der Tat das Ergebnis von Sysutils.ExecuteProcess abgewartet und abhängig hiervon die Schleife gestartet.

Kann es sein , dass OpenOffice bzw. Sysutils.ExecuteProcess die 0 bei Erfolg zu früh liefert???



MfG, P. Jensen

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Frage zu Sysutils.ExecuteProcess

Beitrag von mse »

Probiere doch einmal via ExecuteProcess OpenOffice ohne -headless -pt zu starten und kontrolliere, ob dann ExecuteProcess erst beim beenden von OpenOffice zurückkehrt. Falls dies funktioniert, müsste untersucht werden, was -headless alles bewirkt (child-Prozesse, server-Process...).

pjensen
Beiträge: 77
Registriert: Fr 27. Jul 2007, 08:43
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Nahe Flensburg

Re: Frage zu Sysutils.ExecuteProcess

Beitrag von pjensen »

@ _X_

mal eben folgendes ausprobiert (direkt aus dem Wiki übernomen):

Code: Alles auswählen

AProcess := TProcess.Create(nil);
AProcess.CommandLine := soffice+' -headless -pt PDF-Konverter '+OOO_Files;
// We will define an option for when the program
// is run. This option will make sure that our program
// does not continue until the program we will launch
// has stopped running.                vvvvvvvvvvvvvv
AProcess.Options := AProcess.Options + [poWaitOnExit];
AProcess.Execute;
AProcess.Free;
 
ErgFile:='Test';
Merge_PDF(PDF_Files,ErgFile);
Sysutils.ExecuteProcess('/opt/kde3/bin/kpdf',ErgFile);
Das funktioniert auch nicht. Auch hier schmiert der folgende Merge-Befehl wegen (noch) nicht vorhandener PDF-Files ab.


Was soll mir das jetzt sagen??
Liefet OpenOffice zu früh ein OK oder so??

MfG, P. Jensen

pjensen
Beiträge: 77
Registriert: Fr 27. Jul 2007, 08:43
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Nahe Flensburg

Re: Frage zu Sysutils.ExecuteProcess

Beitrag von pjensen »

Naja, wie auch immer, so funktioniert es:

Code: Alles auswählen

if Sysutils.ExecuteProcess(soffice,' -headless -pt PDF-Konverter '+OOO_Files) = 0 then
  Begin
   Repeat
   until FileExists(LastPDF); // warten bis die letzte Datei in pdf gewandelt ist
   Delay(100);  // warten bis die letzte pdf-Datei Datei komplett fertig geschrieben ist...
   ErgFile:='/home/peter/test.pdf';
   Merge_PDF(PDF_Files,ErgFile);
   Sysutils.ExecuteProcess('/opt/kde3/bin/kpdf',ErgFile);
  end;
MfG, P. Jensen

Socke
Lazarusforum e. V.
Beiträge: 3177
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Frage zu Sysutils.ExecuteProcess

Beitrag von Socke »

Gedit hat ein ähnliches Verhalten, wenn schon eine Datei geöffnet ist. In dem Falle wird die neue Datei in dem bereits vorhandenen Prozess geöffnet und aufgerufene liefert 0 zurück.

Eine andere Lösung könnte evtl. dieses Python-Script darstellen: http://www.artofsolving.com/opensource/pyodconverter
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Antworten