I have a WebBrowser control in a VB.NET WinForms app. I am able to set the default printer from code and print without prompting the user. However, there is also a print button that shows the PrintDialog. If this action is done first the page will print. Then if I try to programmatically print later (again setting the default printer to some other printer) the it will print to the last printer selected in the PrintDialog box even though I am resetting the default and see the default printer being changed in Windows.
Any ideas?
It works fine unless ShowPrintDialog has a printer chosen first. Once that occurs it seems to always use that printer no matter what I do.
For Each strPrinter In PrinterSettings.InstalledPrinters
If strPrinter.Contains("My Printer") Then
wScript.SetDefaultPrinter(strPrinter)
End If
Next
browser.Print()
I was able to get the following code to work, without having to open/close a separate form.
I've only been looking for this since IE6...
See also these two posts.
Programmatically changing the destination printer for a WinForms WebBrowser control
Print html document from Windows Service without print dialog
// Add references for: COM: Microsoft Internet Controls; .NET: System.Management.dll
using System;
using System.Reflection;
using System.Threading;
using SHDocVw;
using System.Windows.Controls;
using System.Management;
namespace HTMLPrinting
{
public class HTMLPrinter
{
private bool documentLoaded;
private bool documentPrinted;
private string originalDefaultPrinterName;
private void ie_DocumentComplete(object pDisp, ref object URL)
{
documentLoaded = true;
}
private void ie_PrintTemplateTeardown(object pDisp)
{
documentPrinted = true;
}
public void Print(string htmlFilename, string printerName)
{
// Preserve default printer name
originalDefaultPrinterName = GetDefaultPrinterName();
// set new default printer
SetDefaultPrinter(printerName);
// print to printer
Print(htmlFilename);
}
public void Print(string htmlFilename)
{
documentLoaded = false;
documentPrinted = false;
InternetExplorer ie = new InternetExplorer();
ie.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(ie_DocumentComplete);
ie.PrintTemplateTeardown += new DWebBrowserEvents2_PrintTemplateTeardownEventHandler(ie_PrintTemplateTeardown);
object missing = Missing.Value;
ie.Navigate(htmlFilename, ref missing, ref missing, ref missing, ref missing);
while (!documentLoaded && ie.QueryStatusWB(OLECMDID.OLECMDID_PRINT) != OLECMDF.OLECMDF_ENABLED)
Thread.Sleep(100);
ie.ExecWB(OLECMDID.OLECMDID_PRINT, OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, ref missing, ref missing);
// Wait until the IE is done sending to the printer
while (!documentPrinted)
Thread.Sleep(100);
// Remove the event handlers
ie.DocumentComplete -= ie_DocumentComplete;
ie.PrintTemplateTeardown -= ie_PrintTemplateTeardown;
ie.Quit();
// reset to original default printer if needed
if (GetDefaultPrinterName() != originalDefaultPrinterName)
{
SetDefaultPrinter(originalDefaultPrinterName);
}
}
public static string GetDefaultPrinterName()
{
var query = new ObjectQuery("SELECT * FROM Win32_Printer");
var searcher = new ManagementObjectSearcher(query);
foreach (ManagementObject mo in searcher.Get())
{
if (((bool?)mo["Default"]) ?? false)
{
return mo["Name"] as string;
}
}
return null;
}
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 true;
}
}
}
I created a form with nothing on it. The action of launching/closing this form made it go to the right printer... I have no idea why that works, but there must be some function that could be called to simulate whatever action is taking place there.