2013-10-04 5 views
1

У меня проблемы с веб-браузером COM при попытке распечатать их через несколько раз.
Для репликации проблемы:Печать из веб-браузера дважды

1) Создать новый "Windows Forms" проект
2) Добавить COM ссылку на "Controls Интернет Microsoft"
3) Добавить обозревательУправление "webbrowser1" и кнопка "button1" в форма (с панели инструментов)
4) Убедитесь, что у вас есть файл "C: \ index.html"
5) Добавьте этот код ...

Option Explicit On 

Imports System.IO 
Imports System.Reflection 
Imports System.Diagnostics.Process 
Imports System.Runtime.InteropServices 
Imports SHDocVw 

Public Class Form1 
Dim WithEvents p As New PrintHTML 
Dim htmlfilename As String 

Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing 
    p = Nothing 
End Sub 

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
    htmlfilename = "c:\index.html" 
    WebBrowser1.Navigate(htmlfilename) 
End Sub 

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
    p.PrintHTMLDocument(htmlfilename) 
End Sub 
End Class 

Public Class PrintHTML 

Dim documentLoaded As Boolean = False 
Dim documentPrinted As Boolean = False 

Public Sub PrintHTMLDocument(ByVal htmlfilename As String) 

    Dim ie As New InternetExplorer 
    AddHandler DirectCast(ie, InternetExplorer).PrintTemplateTeardown, AddressOf PrintedCB 
    AddHandler DirectCast(ie, InternetExplorer).DocumentComplete, AddressOf LoadedCB 

    ie.Navigate(htmlfilename) 
    While Not documentLoaded AndAlso ie.QueryStatusWB(OLECMDID.OLECMDID_PRINT) <> OLECMDF.OLECMDF_ENABLED 
     Application.DoEvents() 
     Threading.Thread.Sleep(100) 
    End While 

    Try 
     ie.ExecWB(OLECMDID.OLECMDID_PRINT, OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, vbNull, vbNull) 
     While Not documentPrinted 
      Application.DoEvents() 
      Threading.Thread.Sleep(100) 
     End While 
    Catch ex As Exception 
     Debug.Print(ex.Message) 
    End Try 
End Sub 

Private Sub LoadedCB(ByVal obj As Object, ByRef url As Object) 
    documentLoaded = True 
End Sub 

Private Sub PrintedCB(ByVal obj As Object) 
    documentPrinted = True 
End Sub 
End Class 

Когда я нажимаю button1 впервые everiything ведет себя, как и ожидалось (начинается печать), но когда я нажимаю на button1 для печати более чем один раз - вместо печати я получаю сообщение об ошибке:

Первый шанс исключение типа «System.Runtime.InteropServices.COMException» произошло в my.exe
Попытка отменить цель падение, которое не было зарегистрировано (Исключение из HRESULT: 0x80040100 (DRAGDROP_E_NOTREGISTERED))

что может вызвать эту ошибку и как я могу избавиться от него, чтобы быть в состоянии напечатать документ более чем один раз с описанными компонентами?

ответ

1

Возможно, вы забыли установить documentLoaded и documentPrinted обратно в false перед тем как позвонить по телефону Navigate. Они остаются true от последней распечатки, и ваша логика ожидания для события в цикле не работает. I.e., это должно быть:

documentLoaded = False 
documentPrinted = False 
ie.Navigate(htmlfilename) 
While Not documentLoaded AndAlso ie.QueryStatusWB(OLECMDID.OLECMDID_PRINT) <> OLECMDF.OLECMDF_ENABLED 
    Application.DoEvents() 
    Threading.Thread.Sleep(100) 
End While 

Существует еще одна проблема. По-видимому, вы не используете повторно объект InternetExplorer в PrintHTMLDocument и создаете новый экземпляр каждый раз, когда вы печатаете. Если по какой-то причине вы не хотите повторно использовать его, вы должны хотя бы позвонить ie.Quit в конце PrintHTMLDocument. В противном случае вы полагаетесь на сборщик мусора .NET, чтобы освободить объект (который является объектом автоматизации COM вне процесса, каждый из которых использует некоторые существенные системные ресурсы). Если вы собираетесь повторно использовать его, убедитесь, что вы только добавляете обработчики событий один раз.

+1

Да, это все! Спасибо, Носератио. Теперь мой код работает точно так, как ожидалось. Я должен использовать новый экземпляр для печати документа, но я не знаю, почему часть моего кода отсутствует? Возможно, я написал «слишком быстро». Да, после каждой печати я удаляю обработчики, вызываю ie.Quit и устанавливаю ie = Nothing. Я понимаю, что этого достаточно, чтобы очистить объект. –

+0

Без проблем, рад, что это помогло. Вы должны быть в порядке, если вы выполните такую ​​очистку. – Noseratio

Смежные вопросы