Hallo zusammen
Ich habe einen Code geschrieben, der mir eine PDF-Datei herunterlädt und diese anschliessend mit dem Acrobat Reader des Sytems öffnet.
Den Acrobat Reader starte ich als Process p (global definiert). Dadurch habe ich die Möglichkeit, auf den Prozess zu warten, ihn zu zerstören oder seinen exit-status abzurufen.
Der unten beschriebene Code wird ausgeführt, wenn ich in einer GUI den entsprechenden Button klicke. Der Code darin wird in einem eigenen Thread ausgeführt.
Der Ablauf des Codes ist direkt darin als kommentar beschrieben, die Problemstellung darunter:
Lasse ich diesen Code auf einer Linux-Maschine laufen, läuft es perfekt. Die Applikation wird zur Laufzeit von Acrobat Reader gesperrt, sodass ich nichts am Befund ändern kann, bis Acrobat wieder geschlossen ist. Auch das Löschen der temporären PDF-Dateien funktioniert einwandfrei.
Sprich Linux wartet tatsächlich auf die Methode p.waitFor() bzw p.exitValue();, bis es den weiteren Code ausführt.
Nun zum eigentlichen Problem:
Auf Windows, worauf die Applikation primär laufen muss, wird überhaupt gar nicht gewartet auf das Ende des Acrobat Prozesses. Der Code nach der p.waitFor()-Methode wird schon ausgeführt während das PDF-File noch im Acrobat Reader geöffnet ist.
Das heisst, die graphische Oberfläche wird für ein paar Millisekunden gesperrt und dann gleich wieder entsperrt. Die Methode
deleteBefuende(); wird auch gleich ausgeführt und löscht die erst geladene PDF-Datei auch gleich mit und kann somit von Acrobat Reader schon gar nicht mehr geöffnet werden. D.h. Acrobat Reader wird zwar geöffnet, aber mit einer Fehlermeldung, dass die Datei nicht vorhanden sei.
Da der Code unter Linux perfekt funktioniert, gehe ich kaum davon aus, dass der falsch ausformuliert wurde. Das Problem hat viel eher mit dem Betriebssystem zu tun, unter dem die Applikation läuft.
Warum verhält sich Windows so und nicht wie dem Code entsprechend zu erwarten ist? Habe ich irgendwas nicht beachtet ?
Ich konnte dieses Problem einzig mit einem gut durchdachten sleep (auf die zu erwartende Zeit, die man benötigt um das Dokument zu betrachten) ein bisschen umgehen. Aber sleep's einbauen ist wohl unterste Schublade in der Programmierung, sofern es nicht wirklich vernünftige Gründe für diese Überlegung gibt. Hier sind die Gründe jedoch nur notgedrungen.
Ich bin dankbar um jeden Hinweis.
P.S. Es ist echt tragisch, wie oft der Code einwandfrei unter Linux ausgeführt werden kann, während es unter Windows überhaupt nicht funktioniert...Ich habe manchmal echt das Gefühl, dass es bei Windows auf Parameter wie die Wetterlage und Windrichtung ankommt, ob etwas läuft oder nicht.. [ironie off]
Ich habe einen Code geschrieben, der mir eine PDF-Datei herunterlädt und diese anschliessend mit dem Acrobat Reader des Sytems öffnet.
Den Acrobat Reader starte ich als Process p (global definiert). Dadurch habe ich die Möglichkeit, auf den Prozess zu warten, ihn zu zerstören oder seinen exit-status abzurufen.
Der unten beschriebene Code wird ausgeführt, wenn ich in einer GUI den entsprechenden Button klicke. Der Code darin wird in einem eigenen Thread ausgeführt.
Der Ablauf des Codes ist direkt darin als kommentar beschrieben, die Problemstellung darunter:
Code:
(new Thread() {
public void run() {
// das PDF wurde erfolgreich heruntergeladen
if (befundAufbereiten() == true) {
hideWaiting();
setUnlockForBefund(false); // sperre die graphische Oberfläche (buttons, textfelder usw.)
try {
if (p != null) {
p.destroy(); // zerstört allfällige prozesse, die vorhin geöffnet waren
}
// je nach betriebssystem wird der acrobat reader anders aufgerufen
// damit wäre das PDF geöffnet
if (os.toLowerCase().indexOf("windows") != -1) {
p = Runtime.getRuntime().exec(new String[]{ "rundll32", "url.dll,FileProtocolHandler", tmpFile });
}
if (os.toLowerCase().indexOf("linux") != -1) {
p = Runtime.getRuntime().exec("/usr/bin/acroread "+tmpFile);
}
// warte solange, bis der prozess beendet wird
p.waitFor();
int exit = p.exitValue(); // hole den exit status
if (exit == 0) { // beendung erfolgreich
setUnlockForBefund(true); // entsperre die graphischeh oberfläche
deleteBefuende(); // lösche alle pdf-dateien im temporären dowload-ordner
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
showWarning(getString("Hinweis"), getString("wysiwygFailed").replace("XXXXXX", String.valueOf(auftragNr)));
}
}
}).start();
showWaiting(getString("oneMoment"));
Lasse ich diesen Code auf einer Linux-Maschine laufen, läuft es perfekt. Die Applikation wird zur Laufzeit von Acrobat Reader gesperrt, sodass ich nichts am Befund ändern kann, bis Acrobat wieder geschlossen ist. Auch das Löschen der temporären PDF-Dateien funktioniert einwandfrei.
Sprich Linux wartet tatsächlich auf die Methode p.waitFor() bzw p.exitValue();, bis es den weiteren Code ausführt.
Nun zum eigentlichen Problem:
Auf Windows, worauf die Applikation primär laufen muss, wird überhaupt gar nicht gewartet auf das Ende des Acrobat Prozesses. Der Code nach der p.waitFor()-Methode wird schon ausgeführt während das PDF-File noch im Acrobat Reader geöffnet ist.
Das heisst, die graphische Oberfläche wird für ein paar Millisekunden gesperrt und dann gleich wieder entsperrt. Die Methode
deleteBefuende(); wird auch gleich ausgeführt und löscht die erst geladene PDF-Datei auch gleich mit und kann somit von Acrobat Reader schon gar nicht mehr geöffnet werden. D.h. Acrobat Reader wird zwar geöffnet, aber mit einer Fehlermeldung, dass die Datei nicht vorhanden sei.
Da der Code unter Linux perfekt funktioniert, gehe ich kaum davon aus, dass der falsch ausformuliert wurde. Das Problem hat viel eher mit dem Betriebssystem zu tun, unter dem die Applikation läuft.
Warum verhält sich Windows so und nicht wie dem Code entsprechend zu erwarten ist? Habe ich irgendwas nicht beachtet ?
Ich konnte dieses Problem einzig mit einem gut durchdachten sleep (auf die zu erwartende Zeit, die man benötigt um das Dokument zu betrachten) ein bisschen umgehen. Aber sleep's einbauen ist wohl unterste Schublade in der Programmierung, sofern es nicht wirklich vernünftige Gründe für diese Überlegung gibt. Hier sind die Gründe jedoch nur notgedrungen.
Ich bin dankbar um jeden Hinweis.
P.S. Es ist echt tragisch, wie oft der Code einwandfrei unter Linux ausgeführt werden kann, während es unter Windows überhaupt nicht funktioniert...Ich habe manchmal echt das Gefühl, dass es bei Windows auf Parameter wie die Wetterlage und Windrichtung ankommt, ob etwas läuft oder nicht.. [ironie off]