1

I want to Print my HTML document directly to a specific network printer without printer dialog window when the end user click on PRINT button. I do search and follow this but this opens a dialog window to save the document as pdf.

Based On The Comments:

 public static class PrinterClass
    {
        [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SetDefaultPrinter(string Printer);
    }


    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            //List<string> st = new List<string>();

            //foreach (string strPrinter in PrinterSettings.InstalledPrinters)
            //{
            //    if (strPrinter.Contains("My Printer"))
            //    {
            //        PrinterClass.SetDefaultPrinter(strPrinter);
            //    }
            //    st.Add(strPrinter);
            //}

            SetDefaultPrinter("Send To OneNote 2016");
        }

        WebBrowser webBrowser = new WebBrowser();
        void Print(string str)
        {
            webBrowser.DocumentText = str;

            webBrowser.DocumentCompleted += webBrowser_DocumentCompleted;
        }
        void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            IHTMLDocument2 d2;
            d2 = (IHTMLDocument2)((WebBrowser)sender).Document.DomDocument;

            d2.execCommand("Print", false, null);
        }

        private void btn_print_Click(object sender, EventArgs e)
        {
            Print("<html><body>..some html code..</body></html>");
        }

        public static bool SetDefaultPrinter(string defaultPrinter)
        {
            using (ManagementObjectSearcher objectSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_Printer"))
            {
                using (ManagementObjectCollection objectCollection = objectSearcher.Get())
                {
                    foreach (ManagementObject mo in objectCollection)
                    {
                        if (string.Compare(mo["Name"].ToString(), defaultPrinter, true) == 0)
                        {
                             mo.InvokeMethod("SetDefaultPrinter", null, null);
                            return true;
                        }
                    }
                }
            }
            return false;
        }
    }
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
Anyname Donotcare
  • 11,113
  • 66
  • 219
  • 392
  • You'll have to cast the `WebbBrowser.Document` to [IHtmlDocument2](https://learn.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa752577(v=vs.85)). In the `[IHtmlDocument2].execCommand("Print", false, ...)` method, `false` means: do not display the user interface. Which, btw, is the default. – Jimi Jul 26 '19 at 16:39
  • @Jimi Could U clarify it on my code please, with more details – Anyname Donotcare Jul 26 '19 at 16:43
  • 1
    Well, add a reference to `mshtml`, then you have all the standard IE11/Edge interfaces available. `IHtmlDocument2` provides the `execCommand("Print")` method. `IHTMLDocument2 document = ((WebBrowser)sender)Document..DomDocument as IHTMLDocument2; document.execCommand("Print", false, null);`. (Writing here, should be ~correct), Add a `using mshtml;` – Jimi Jul 26 '19 at 16:56
  • 1
    There are two COM references. One is `Microsoft Internet Controls`, the other is `Microsoft Html Object Library`. IIRC, you just need the latter. There's the catch that often the GAC has an old library in storage which it's very fond of and doesn't want to let go. If that's the case (you won't find `IHtmlDocument7` and `IHtmlDocument8`, for example), you'll have to rebuild the type library. – Jimi Jul 26 '19 at 17:02
  • I just recalled that I've posted a few notes about this [here](https://stackoverflow.com/a/54390001/7444103). – Jimi Jul 26 '19 at 17:14
  • @Jimi I edit my question based on your recommendation, but still I get the `dialog printing window popup` when I click on the Print button!, Could U take a look on my code please – Anyname Donotcare Jul 26 '19 at 20:56
  • 1
    Now, I have a doubt on what the problem really is. If you execute this: `var wb = new WebBrowser(); wb.Navigate(""); wb.Document.Write("..some html code.."); wb.Refresh(); wb.Print();`, what happens? – Jimi Jul 27 '19 at 06:54
  • @Jimi I think this works because I get the dialog window only if the default printer `print to file like pdf`, I don't have a printer at home, so I can't be 100% sure if it works :( Is there any way to ensure that it works with real printers without the dialog window? – Anyname Donotcare Jul 27 '19 at 10:32
  • 1
    Well, I've tested it with my printer before asking you to try it out. It prints directly to the default printer (without asking to choose one, if that was the actual problem). – Jimi Jul 27 '19 at 10:34
  • 1
    @AnynameDonotcare Showing save dialog of the pdf printer is because of the behavior of that printer. So if it doesn't show print dialog, it means it's working. You can also try using virtual printers like OneNote which doesn't ask to save the file and just print the file in OneNote without any prompt. – Reza Aghaei Jul 27 '19 at 14:49
  • @Jimi I'm so grateful, I'll double test it tomorrow – Anyname Donotcare Jul 27 '19 at 15:11

1 Answers1

2

In the recent versions of the WebBroswer control, Print() prints to the default printer without showing any dialog:

webBrowser1.Print();

It's equivalent to getting an instance of IWebBrowser2 from the WebBrowser.ActiveXInstance property and then call its ExecWB method by passing OLECMDID_PRINT as command and OLECMDEXECOPT_DONTPROMPTUSER to specify not showing the prompt:

int OLECMDID_PRINT = 6;
int OLECMDEXECOPT_DONTPROMPTUSER = 2;
dynamic iwb2 = webBrowser1.ActiveXInstance;
iwb2.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, null, null);

Or in a single line of code:

((dynamic)webBrowser1.ActiveXInstance).ExecWB(6, 2, null, null);
Marc.2377
  • 7,807
  • 7
  • 51
  • 95
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398