2010-12-17 5 views
3

Ich habe eine Python-Anwendung, die wiederholt ausgeführt wird. Es speichert ein PDF als Datei und druckt es dann aus. Wenn das Drucken beendet wird, löscht es die Datei.Drucken Sie ein PDF und löschen Sie die Datei, wenn der Druckvorgang beendet ist

Meine aktuelle Lösung (für den Druck und löscht Teil), ist dies:

win32api.ShellExecute(0, "print", file_path, None, ".", 0) 
time.sleep(10) 
os.remove(self.options.dest_name) 

time.sleep(10) ein Trick ist dem Druckprozess, die Zeit zu geben, bevor das Löschen von Dateien auszuführen. Ohne es öffnet sich Acrobat Reader (es öffnet sich trotzdem) und warnt, dass es die Datei nicht finden kann. Dies liegt daran, dass die Dateientfernung bereits erfolgt ist.

Die Frage ist:

  1. wie kann ich es ohne diese unzuverlässig Trick? Am besten wäre es, einen Handler für den Druckvorgang zu haben und eine Information über den Druckstatus zu bekommen: Ich warte darauf, dass es fertig ist und ich lösche die Datei.

  2. wäre es noch besser, wenn Acrobat Reader nicht öffnen würde, aber das ist kein großes Problem.

EDIT: Ich habe versucht, als Standard-PDF-Reader zu Foxit Reader Schalten und jetzt ist es nicht öffnen, wenn ich nicht will. ;)

ANDERE MÖGLICHE LÖSUNG: zyklisch überprüfen, ob die Datei vorhanden ist (nicht von einem anderen Prozess verwendet wird) und wenn es wieder löschen es verfügbar ist. Wie könnte ich das in Python machen?

+2

Ehrlich gesagt, gibt es keinen wirklichen Weg, etwas zu wissen, ob * eigentlich * gedruckt. Es gibt 100 verschiedene Probleme, die in der Druckwarteschlange auftreten können und die Ihnen nie gemeldet werden. –

+0

@Nick Mhm, sagen wir, ich muss nur wissen, wann das Dokument an den Drucker gesendet wurde. Also kann ich es wegwerfen. – bluish

Antwort

4

Endlich habe ich eine gute Lösung gefunden, dank this answer (und auch @Lennart es auf einem Kommentar erwähnt):

install Ghostscript

install GSview

schreiben (die gsprint.exe beinhaltet), um diese code:

file_path = "C:\\temp\\test.pdf" 
p = subprocess.Popen(["C:\\Ghostgum\\gsview\\gsprint.exe", "-printer", printer_name, "-colour", file_path], 
     stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
stdout, stderr = p.communicate() # waits for the gs process to end 
os.remove(file_path) # now the file can be removed 

Keine Acrobat-Fenster öffnen, keine Datei vor dem Drucken entfernt ing ... Der Ärger: GS installieren.

Siehe auch: gsprint reference

2

Anstatt einen Dateinamen hart zu codieren und diesen zu drucken, sollten Sie das Modul tempfile verwenden, um eine temporäre Datei mit einem eindeutigen Namen zu erstellen.

import tempfile 
file_name = tempfile.NamedTemporaryFile(suffix=".pdf", delete=False) 

Wenn Sie möchten, können Sie eine regelmäßige ordentlich-up-Skript Fensters Scheduling-Tools ausführen, um die Dateien erstellt zu löschen.

+0

Sie haben Recht, aber in meinem Fall, wenn Sie einen Befehlszeilenparameter auswählen, kann der Benutzer wählen, ob er das Dokument drucken oder speichern möchte. Ich bevorzuge es, es als eine Datei zu speichern, und, wenn der Benutzer entschied, es zu drucken und zu löschen, diese Operationen ausführend. – bluish

1

Adobe Acrobat hat (oder hatte zumindest) einen Parameter "/ t", der es geöffnet, gedruckt und beendet hat. Wenn Sie es verwenden, können Sie den acrobat reader aufrufen und darauf warten, dass er beendet wird, und dann die Datei löschen.

Ungeprüfte Code:

>>> import subprocess 
# You will have to figure out where your Acrobate reader is located, can be found in the registry: 
>>> acrobatexe = "C:\Program Files\Adobe\Acrobat 4.0\Reader\AcroRd32.exe" 
>>> subprocess.call([acrobatexe, "/t", tempfilename, "My Windows Printer Name"]) 
>>> os.unlink(tempfilename) 

So ähnlich.

Wenn Sie nicht möchten, dass Acrobat geöffnet wird, gibt es Open-Source-Software, die PDF-Dateien über die Befehlszeile ausgibt. Du könntest eins mit deiner Software einschließen.

+0

Danke! Die Open Source Sw, die du sagst, sind das etwas, was ich in mein Python-Programm importieren kann? Können Sie mir bitte einen vorschlagen? – bluish

+1

Nicht importieren, vielleicht, aber mindestens anrufen. Du kannst es mit Ghostscript machen, aber das ist ein ziemlich großes Programm, du könntest bessere finden. Ich bin kein Experte für dieses Thema. Sie können eine andere Frage stellen oder Google fragen. :) –

0

Warum nicht os.system verwenden, die warten, bis der Prozess abgeschlossen ist?

+0

@Jason In welcher Weise? Wie kann ich diesen spezifischen Prozess anzeigen, den ich mit win32api.ShellExecute (...) gestartet habe? – bluish

+0

Ich meine, verwenden Sie os.system (Befehl), um einen Prozess zu starten, der den Druck ausführt, anstatt win32api.ShellExecute zu verwenden. Es wird warten, bis der Prozess abgeschlossen ist und dann seinen Beendigungscode zurückgeben. – JasonFruit

+0

(Ich sehe, ich missverstehe win32api.ShellExecute.) Zum Beispiel könnten Sie os.system verwenden, um Adobe Reader mit Lennart's/t-Schalter zu starten. – JasonFruit

Verwandte Themen