Announcement

Collapse
No announcement yet.

Schließen des Acrobat Readers nach dem Ausdruck einer PDF-Datei

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Schließen des Acrobat Readers nach dem Ausdruck einer PDF-Datei

    Hallo allerseits,

    Nur weil ich gerade selber goooooglen mußte ;-)

    PDF's kann man ja aus VBA heraus schön mit ShellExecute & "print" ausdrucken.

    (Diese Möglichkeit funktioniert, die ActiveX-Kommunikation mit dem Acrobat Reader aus VBA heraus schlägt hingegen meist fehl (nicht nur meine Erfahrung).)

    Das Problem mit ShellExecute ist aber, daß der Acrobat Reader nach dem Druck offen stehen bleibt.

    Schließen kann man den Reader, indem man eine WM_CLOSE - Nachricht (&H10)
    (also nicht WM_COMMAND+SC_CLOSE und auch nicht WM_QUIT) an das Fenster des Readers schickt (mittels postMessage).

    Das Fensterhandle zum Schicken findet man mittels FindWindowA( "AdobeAcrobat", 0&).

    (In diesem Fall war es VBA unter Access XP)

    Grüße allerseits,
    tAgedObject
    darkness is a state of mind

  • #2
    Der Verwendungshintergrund ist zwar nicht gerade VBA sondern eher VB.NET, aber das Problem, dass Acrobat offen bleibt, ist ja das gleiche, daher ein paar Nachfragen:

    Kann man davon ausgehen, dass die Nachricht sofort gesendet werden kann, oder muss man warten, um den Druck nicht zu unterbrechen? Also mit anderen Worten: wartet Acrobat mit der Bearbeitung der WM_CLOSE-Nachricht bis er fertig gedruckt hat, oder bricht er dann den Druck ab?

    Und geht das auch, wenn man den Druck per Process.Start mit den Kommandozeilenparametern /p /h ("print" und "hidden") gestartet hat? (Soweit ich weiß gibt es keine Möglichkeit, per ShellExecute "print" den Acrobat minimiert zu starten, oder doch?)

    Falls ich nach Process.Start nicht einfach aus dem Prozess das MainWindowHandle ziehen kann kommennoch Fragen hinzu:

    Kann ich sofort nach dem Druckstart mein FensterHandle ziehen, oder kommt der Aufruf zurück, bevor Acrobat das Fenster geöffnet hat?

    Und was passiert, wenn man mehrere Dokumente drucken will? Hat man da die Möglichkeit beim Handle suchen das letzte Fenster zu selektieren? Oder muss man so lange das Handle erfragen, bis man nichts mehr bekommt (der alte Druck also beendet und das Fenster geschlossen ist), bevor man den nächsten Druck startet?

    Fragen über Fragen, und dabei spiele ich noch nicht einmal des Teulels Advokat...

    Gruß und schönes Wochenende
    Martin Dietz

    Comment


    • #3
      Ich weis aber auch nicht alles ;-)

      Hallo,

      Aus meiner Sicht ist shellExecute kein alternativer Weg einen Prozess zu starten,
      sondern eine alternative Herangehensweise an die Arbeit - nämlich dokumentenzentriert.

      In der Registry sind für Dokumente Shell-Operationen registriert, z.B. auch Print.
      Das dort registrierte Kommando wird dann durch die Shell ausgeführt.

      Im Fall von PDF's steht halt genau der Befehl mit /p /h drin - das hat also die gleiche Auswirkung.

      Im Gegensatz dazu ist der Befehl Process.Start aus VB.NET offenbar nicht in der Lage (habe ich nur kurz (nicht gründlich) angetestet) tatsächlich ordentlich mit den Argumenten umzugehen.
      Es gibt allerdings auch Process.ShellExecute (habe ich noch nicht selbst probiert).

      In der Routine, wo ich das brauchte, habe ich eine Schleife gemacht, die einfach über einen (per Parameter angebbaren Zeitraum) lang versucht, das Haupthandle des Fensters von Acrobat zu erhalten und dann den Post-befehl sendet.

      Bevor ich überhaupt mit dem Drucken beginne, schaue ich nach, ob der Reader nicht vorher geöffnet ist - falls ja, dann schließe ich diesen nicht.

      Nur eine ungeprüfte Schätzung :
      Wenn man mehrere Dokumente druckt, sollte das eigentlich auch funktionieren.
      Wenn ich mal Zeit habe, werde ich's versuchen - falls Du's eher machst, kannst Du ja mal die Ergebnisse posten ;-)

      Wenn mal mal ehrlich ist, müßte man das Ganze so implementieren, daß man herausbekommt, wann der Druckjob fertig ist und danach einfach den Prozess beendet. Das war mir aber an dieser Stelle zu aufwändig.

      Grüße,
      tAgedObject
      darkness is a state of mind

      Comment


      • #4
        Nun, ShellExecute setzt voraus, dass für den Befehl "print" auch bei jedem Anwender überhaupt etwas hinterlegt ist, und dann auch noch mit den richtigen Parametern, wenn man sich eine ProcessStartInfo-Struktur aufbaut, kann man die Parameter mitgeben. Selbst wenn ich davon ausgehe, dass der Anwender selbst an diesen Einstellungen nicht rumgefummelt hat, und andere Programme eingetragen hat, so kann ich nicht mit Sicherheit davon ausgehen, dass der hidden-Parameter eingetragen ist.

        Parameterübergabe an die aufrufende Funktion hat bei mir eigentlich noch keine Probleme verursacht.

        Nun zum Schließen selbst: ich habe es mal ausprobiert. Wenn Acrobat noch dabei ist, zu drucken, wird das WM_CLOSE ignoriert, d.h. er bricht den Druck nicht ab, aber das Fenster schließt sich auch nicht. Gibt es eine Möglichkeit, festzustellen, ob der Druck beendet ist, oder muss ich in einer Schleife so lange WM_CLOSE schicken, bis ich das Handle eben nicht mehr kriege?

        Gruß
        Martin

        Comment


        • #5
          Ich binde auch nur eine Schleife

          Hallo,

          Das Nachguggen, ob der Druck noch läuft war mir zu umständlich,
          deswegen mache ich auch nur eine Schleife,
          in welcher ich mir immer das Handle hole und WM_CLOSE schicke.
          Dabei wird nicht überprüft, ob es ein Handle gibt.

          Das klappt bei mir erstmal.

          Mann kann natürlich nachguggen, ob noch gedruckt wird.
          Hierfür kann man wohl auch WMI benutzen.
          ...
          Win32_Printer
          Win32_PrinterConfiguration
          Win32_PrinterDriver
          Win32_PrintJob
          ...


          Habe ich aber selbst noch nicht gemacht....

          Grüße,
          tAgedObject
          darkness is a state of mind

          Comment


          • #6
            Da mehrere User auf den gleichen Printer zugreifen, nützt es leider nichts, die Printer Queue im Auge zu behalten, man müsste also einen Weg finden, den Druckjob zu identifizieren, den Acrobat gerade abgeschickt hat, und sobald der in der PrinterQueue auftaucht Acrobat zu beenden, aber im Endeffekt gebe ich Dir recht, am einfachsten ist es, WM_CLOSE so lange abzuschicken, bis kein Handle mehr greifbar ist, und wenn ich eh eine Polling-Schleife brauche (ob ich nun ein Handle oder die Druckerwarteschlange abfrage ist dann auch egal), kann ich es ruhig einfach gestalten.

            Danke
            Martin

            Comment

            Working...
            X