Printing the contents of a WPF WebBrowser

2

I'm trying to print the contents of a WPF WebBrowser control so that no print dialog is shown, but am having no luck.

I have tried the following and am sure it did work:

PrintDialog printDialog = new PrintDialog();
printDialog.PrintDocument(((IDocumentPaginatorSource)browser.Document).DocumentPaginator, "My App");

but for some reason, I'm now getting the following exception:

Unable to cast COM object of type 'mshtml.HTMLDocumentClass' to interface type 'System.Windows.Documents.IDocumentPaginatorSource'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{2C0C27DF-282F-3225-ADCD-CEC68F890EEB}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

The only thing I can think has changed on my PC is that I have installed IE8 since I last tried this, but would that really break it?

wpf
browser
printing
asked on Stack Overflow Aug 19, 2009 by CatBusStop

3 Answers

7
// Send the Print command to WebBrowser. For this code to work: add the Microsoft.mshtml .NET reference
mshtml.IHTMLDocument2 doc = WebBrowser1.Document as mshtml.IHTMLDocument2;
doc.execCommand("Print", true, null);

Source: http://social.msdn.microsoft.com/Forums/en/wpf/thread/63ae5345-b2ca-45a9-9113-0ddc43e9925b

answered on Stack Overflow Jan 20, 2011 by Tony
3

For silent printing without dialogs, use this code:

private void PrintCurrentPage()
{
    // document must be loaded for this to work
    IOleServiceProvider sp = WebBrowser1.Document as IOleServiceProvider;
    if (sp != null)
    {
        Guid IID_IWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
        Guid IID_IWebBrowser2 = new Guid("D30C1661-CDAF-11d0-8A3E-00C04FC9E26E");
        const int OLECMDID_PRINT = 6;
        const int OLECMDEXECOPT_DONTPROMPTUSER = 2;

        dynamic wb; // should be of IWebBrowser2 type
        sp.QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, out wb);
        if (wb != null)
        {
            // this will send to the default printer
            wb.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, null, null);
        }
    }
}
[ComImport, Guid("6D5140C1-7436-11CE-8034-00AA006009FA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IOleServiceProvider
{
    [PreserveSig]
    int QueryService([MarshalAs(UnmanagedType.LPStruct)] Guid guidService, [MarshalAs(UnmanagedType.LPStruct)]  Guid riid, [MarshalAs(UnmanagedType.IDispatch)] out object ppvObject);
}

WebBrowser silent printing

answered on Stack Overflow Nov 20, 2015 by PostureOfLearning • edited May 23, 2017 by Community
1

To avoid taking a dependency on MSHTML you can simply do:

browser.InvokeScript("execScript", new object[] { "window.print();", "JavaScript" });

I devised the above solution when I was having trouble with a WPF project that was migrated to .Net Core 3 and was using Tony's answer that involves MSHTML reference. Referencing MSHTML in .Net Core is not very straightforward (see this github issue)

answered on Stack Overflow Oct 30, 2019 by Dave M

User contributions licensed under CC BY-SA 3.0