ahstax
Goto Top

Drucken eines PDF aus Webrowser

Hallo miteinander,

ich versuche gerade, ein PDF, das ich in einen Webbrowser lade, ohne User-Dialog zu drucken. Der Webbrowser ist in einer Form. Ich verwende folgenden recherchierten Code (der, vermutlich für Kenner wenig überraschend, leider nicht macht, was ich mir so vorstelle...):

Imports System.Drawing.Printing

Private Enum ExecOpt
  OLECMDEXECOPT_DODEFAULT = 0
  OLECMDEXECOPT_PROMPTUSER = 1
  OLECMDEXECOPT_DONTPROMPTUSER = 2
  OLECMDEXECOPT_SHOWHELP = 3
End Enum

Private Enum Exec
  ...
  OLECMDID_PRINT = 6
  ...
End Enum


Public Sub Drucken()

  Me.WebBrowser1.Navigate(strPDFFileFullPath)

  Try

    Dim strStandardDrucker As String = pd.PrinterSettings.PrinterName

    Shell(String.Format("rundll32 printui.dll,PrintUIEntry /y /n ""{0}""", strDrucker2use))  

    Dim n As Object = Nothing
    Dim MyWeb As Object = Me.WebBrowser1.ActiveXInstance
   
    ' FEHLERAUSLÖSER:  
    MyWeb.ExecWB(OLECMDID.OLECMDID_PRINT, OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, n, n)

  Catch ex As Exception
    MsgBox(ex.Message)
  End Try

 Shell(String.Format("rundll32 printui.dll,PrintUIEntry /y /n ""{0}""", strStandardDrucker))  

End Sub

Die Zeile nach 'FEHLERAUSLÖSER erzeugt den Fehler:
"Es wurde versucht, ein Drop-Ziel zu widerrufen, das nicht registriert wurde. (Ausnahme von HRESULT: 0x80040100 (DRAGDROP_E_NOTREGISTERED))"


Gespielt habe ich auch hiermit:

'Imports SHDocVw  

Dim n As Object = Nothing
Dim wb As SHDocVw.WebBrowser = DirectCast(WebBrowser1.ActiveXInstance, SHDocVw.WebBrowser)
wb.ExecWB(OLECMDID.OLECMDID_PRINT, OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, n, n)

bringt den gleichen Fehler...

Kann mir jemand weiterhelfen?

Neugierige Grüße,
Andreas

Content-Key: 247049

Url: https://administrator.de/contentid/247049

Ausgedruckt am: 29.03.2024 um 07:03 Uhr

Mitglied: colinardo
Lösung colinardo 21.08.2014, aktualisiert am 27.08.2014 um 08:41:02 Uhr
Goto Top
Moin Andreas,
warum nutzt du nicht die zur Verfügung stehende Print-Methode zum Drucken für das System.Windows.Forms.WebBrowser Control
Me.WebBrowser1.Print()
Das druckt bei mir eine Webseite ohne irgendeinen Dialog anzuzeigen ...

Grüße Uwe
Mitglied: ahstax
ahstax 26.08.2014 um 15:53:37 Uhr
Goto Top
Hallo Uwe,

Danke erstmal für Deine Antwort und entschuldige bitte meine verzögerte Reaktion.

Die Sache ist die, dass ich gerne die Abarbeitung meines Codes unterbrechen würde, bis das zu druckende PDF tatsächlich gedruckt wurde. Und das ganze vorzugsweise ohne dass sich Acrobat öffnet. Die Sache mit dem Webbrowser war einer der (letzteren) Versuche. Nun sieht der Code gerade so aus:

Function print(ByVal fname)

Dim psi As New ProcessStartInfo
With psi
 .UseShellExecute = True
 .Verb = "print"  
 .WindowStyle = ProcessWindowStyle.Hidden
 .FileName = fname
End With

Using myProcess As System.Diagnostics.Process = Process.Start(psi)
 'myProcess.WaitForExit()    'Funktioniert nicht bei PDFs, Adobe schließt sich nicht automatisch  
 'myProcess.Kill()  
 System.Threading.Thread.Sleep(3000) 'UNSCHARF  
End Using

 Return (True)

End Function

Damit wird das PDF (im Wesentlichen zuverlässig) gedruckt. Schön wäre aber, das
System.Threading.Thread.Sleep(3000) 'UNSCHARF  
gegen eine Abfrage zu tauschen, ob der Druckvorgang beendet ist. Dass Acrobat offen bleibt, wäre verschmerzbar...

Gibt es da eine Möglichkeit? Vielleicht mit einem anderen, steinigen Pfad?

Neugierige Grüße,
Andreas
Mitglied: colinardo
Lösung colinardo 26.08.2014, aktualisiert am 27.08.2014 um 08:40:53 Uhr
Goto Top
Also für ein Drucken mit Adobe Acrobat könntest du das hier machen:
 Dim ps As New Process
 With ps.StartInfo
     .FileName = "C:\Program Files (x86)\Adobe\Acrobat 10.0\Acrobat\Acrobat.exe"  
     .Arguments = "/h /t ""D:\demo.pdf"" ""HP Laserjet 1320"""  
     .CreateNoWindow = True
 End With
 ps.Start()
 ps.WaitForInputIdle()
 ps.CloseMainWindow()
 MsgBox("Finished Printing")  
Die Doku für die Commandline-Parameter vom Acrobat kannst du hier nachlesen

Wenn du den Standarddrucker schon vorher anderweitig festlegst kannst du deine Funktion nach dem gleichen Schema so umbauen:
Function print(ByVal fname As String)
    Dim psi As New ProcessStartInfo
    With psi
        .Verb = "print"  
        .CreateNoWindow = True
        .FileName = fname
    End With
    Dim myProcess As Process = Process.Start(psi)
    myProcess.WaitForInputIdle()
    myProcess.CloseMainWindow()
    Return (True)
End Function
Bei WaitForInputIdle() kannst als Parameter noch eine maximale Wartezeit in Millisekunden definieren, damit sie im Fall der Fälle nicht ewig hängt.
Grüße Uwe
Mitglied: ahstax
ahstax 27.08.2014 um 08:40:50 Uhr
Goto Top
Hallo Uwe,

Ganz großes Damentennis!!! face-wink

Herzlichen Dank, hat mir sehr(!!) weitergeholfen!

Grüße,
Andreas