Announcement

Collapse
No announcement yet.

Acrobat quittiert WM_CLOSE mit Fehler 1816

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

  • Acrobat quittiert WM_CLOSE mit Fehler 1816

    Hi,

    In einem der anderen Foren (ich glaube es war VBA) wurde geschrieben, dass man den AcrobatReader nach dem Drucken schließen kann, indem man per PostMessage WM_CLOSE an das Fenster sendet. Da die Anwendung und Suche nach Alternativen aber eher in die .NET-Programmierung passen, poste ich es hier.

    Da Acrobat, wenn er noch am Drucken ist, die WM_CLOSE Meldung ignoriert (also nicht einmal in eine eigene Queue steckt um sie später zu verarbeiten), sind wir dort zu dem Schluss gekommen, dass man in einer Schleife so lange WM_CLOSE schicken soll, bis das Fenster weg ist.

    [highlight=vbnet]
    ... ' pro ist hier der Acrobat-Prozess, mit dem gedruckt wird
    Dim hAcrobatWindow As IntPtr
    Do
    hAcrobatWindow = pro.MainWindowHandle
    If PostMessage(hAcrobatWindow, WM_CLOSE, 0, 0) = 0 Then
    clsLog.LogLine("PostMessage an AcrobatReader fehlgeschlagen:" & Err.LastDllError & " - " & Err.Description)
    End If
    Loop While Not pro.HasExited
    [/highlight]

    Das Problem, das nun aufgetreten ist, ist dass das Programm einen Fehler 1816 erhält, wenn es versucht WM_CLOSE abzusetzen. Tante Google sagt mir, dass dies daran läge, dass das Programm die Zahl von 10.000 Postmessages überschritten hätte (ich hatte den entsprechenden Hinweis auf MSDN nie gelesen, weil ich dachte der Betrifft nur Vista und höher, und hier arbeiten alle auf XP). Das Problem trat aber auch auf, als mein Programm frisch gestartet wurde und der Druckbefehl auch einen neuen Acrobat erzeugt hat.

    Nun ist es zwar durchaus möglich, dass ich in die Schleife zum WM_CLOSE senden ein pro.WaitForExit(delay_ms) einbaue, um die PostMessages etwas auseinderzureissen, da das Problem aber anscheind auch bei "jungfräulichen" Programmstarts passiert, habe ich so meine Zweifel, ob das wirklich was bringt.

    Gibt es da irgendwelche Möglichkeiten, festzustellen, ob Acrobat mit dem Drucken fertig ist, um den Acrobat-Prozess zu töten, wenn ich ihm keine PostMessages mehr senden kann? Die einzige Möglichkeit, die mir so auf Anhieb einfällt, wäre die Druckerschlange zu überwachen, bis "mein" Druckauftrag drin ist (identifiziert über Dateiname und User-Kennung des Druckjobs), aber mal davon abgesehen, dass ich nicht weiß, ob das dann nicht den Drucker oder das Netzwerk lahmlegt, da ständig nachzufragen, weiß ich auch nicht, ob ich überhaupt sofort reagieren darf, wenn der Auftrag auftaucht.

    Hat jemand eine Idee, wie man Acrobat dazu bringen kann, den Abschluss des Drucks zurückzumelden, oder wie auf andere Weise von meinem Programm feststellbar ist, ob Acrobat fertig ist?

    Gruß
    Martin

  • #2
    Muss er der Reader sein? Wir habens irgendwann aufgegeben und setzten für dies Jobs Adobe Acrobat vorraus.

    Comment


    • #3
      Hallo,

      habs nicht probiert aber gehts das auch über COM?


      mfG Gü
      "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

      Comment


      • #4
        Originally posted by Bernhard Geyer View Post
        Muss er der Reader sein? Wir habens irgendwann aufgegeben und setzten für dies Jobs Adobe Acrobat vorraus.
        Nun ja, theoretisch nicht, ich ziehe halt mit einer Funktion die Exe, die von Windows aus mit PDF-Dateien verknüpft ist, und mit diesem Programm starte ich dann einen neuen Prozess, dies geht dan aber wieder (wegen der Argumente) davon aus, dass es sich um den Acrobat Reader handelt, oder das programm sich im Aufruf wie der Acrobat Reader verhält.

        ShellExecute mit Kommando "print" zu nutzen geht insofern nicht, da hier in der Firma im Befehl zum Drucken das Argument "/h" fehlt. Grundsätzlich den Adobe Acrobat voraussetzen kann ich nicht, der gehört nicht zur Standardinstallation, aus meinem Programm heraus PDFs drucken soll aber jeder können, und auf die Art bin ich freier, wenn ein Wechsel des PDF-Readers ansteht (so wie neulich von 8 auf 9), oder noch nicht alle Rechner umgestellt sind.

        Ich habe hier mal die beiden involvierten Funktionen aufgeführt:

        [highlight=vbnet]
        Private Function GetPDFPrintExe() As String
        Dim mAcrReaderExePath As String = ""
        Dim c As Boolean = False
        Dim f As String = session.DokDir & "\Dummy.pdf"

        Try
        If Not IO.File.Exists(f) Then c = True : IO.File.Create(f).Close()

        Dim Puffer As New System.Text.StringBuilder(1024)
        Dim Retval As Long = FindExecutable(f, "", Puffer)

        Select Case Retval
        Case 0
        Debug.Print("Es ist nicht genügend Speicher vorhanden, um diese Funktion durchzuführen.")
        Case 31
        Debug.Print("Für diese Datei existiert keine verknüpfte Anwendung!")
        Case SE_ERR_FILE_NOT_FOUND
        Debug.Print("Die angegebene Datei wurde nicht gefunden.")
        Case SE_ERR_PATH_NOT_FOUND
        Debug.Print("Der angegebene Pfad wurde nicht gefunden")
        Case SE_ERR_BAD_FORMAT
        Debug.Print("Die verknüpfte Anwendung ist ungültig oder keine Win32 Anwendung")
        Case Else
        mAcrReaderExePath = Puffer.ToString.Trim
        End Select

        Catch ex As Exception
        ShowError("Fehler in GetPDFPrintExe()" & vbCrLf & ex.ToString)
        mAcrReaderExePath = ""
        Finally
        If c Then FileDelete(f)
        End Try

        Return mAcrReaderExePath
        End Function

        Public Sub PDFDrucken(ByVal pFilename As String)
        Dim f As String = IIf(InStr(pFilename, " ") > 0, Chr(34) & pFilename & Chr(34), pFilename)
        Dim starter As New ProcessStartInfo(GetPDFPrintExe(), " /p /h " & f)
        Dim pro As New Process

        pro.StartInfo = starter
        pro.StartInfo.UseShellExecute = True
        pro.Start()
        Wait(5)

        Dim hAcrobatWindow As IntPtr
        Do
        hAcrobatWindow = pro.MainWindowHandle
        If PostMessage(hAcrobatWindow, WM_CLOSE, 0, 0) = 0 Then
        clsLog.LogLine("PostMessage an AcrobatReader fehlgeschlagen:" & Err.LastDllError & " - " & Err.Description)
        End If
        pro.WaitForExit(1000)
        Loop While Not pro.HasExited
        End Sub
        [/highlight]

        Wie gesagt, das Problem war, dass der nächste Druck erst gestartet werden darf, wenn Acrobat einen Druck abgeschickt hat (da macht Acrobat anscheinend Probleme, wenn er einen Druckprozess aufgedrückt bekommt, bevor der vorherige beendet ist), deshalb darf PDFDrucken nicht zurückkehren, bevor Acrobat fertig ist, weswegen wir Acrobat dann auch nach jedem Druck wieder schließen.

        Irgendwo habe ich mal ein Code-Stück geshen, das PDFs mittels SendFileToPrinter (oder so) druckt, da haben wir aber Probleme bekommen, dass der Drucker damit komplett blockiert war, vermutlich weil das PDF sowohl quer- als auch hochformatige Seiten enthielt.

        Ich hoffe die Voraussetzungen des Problems sind dadurch etwas klarer.

        Gruß
        Martin Dietz

        Comment

        Working...
        X