First, IsValid checks the value of the PrinterName property to see if it is a valid value, not if the printer is connected.
Second, in WPF it is very easy to do this;
var defaultPrintQueue = LocalPrintServer.GetDefaultPrintQueue();
if (!defaultPrintQueue.IsNotAvailable)
{
//print stuff
}
Check the docs for more detail:
In winforms, its a little harder but you can use WMI. Reference System.Management.dll and add the following using statements:
using System;
using System.Drawing.Printing;
using System.Windows.Forms;
using System.Management;
To get all default printers:
NOTE The following code is likely to be OS dependant to some extent. Check the MSDN docs..
var printerSearcher =
new ManagementObjectSearcher(
"SELECT * FROM Win32_Printer where Default = true"
);
return printerSearcher.Get();
The WMI documentation for the printer object describes some useful structures we can look at; PrinterStatus and WorkOffline. We can use these to write an utility class to check the availability of the printer, also check its WorkOffline state...
public static class PrinterUtility
{
public static bool IsOnline(this ManagementBaseObject printer)
{
var status = printer["PrinterStatus"];
var workOffline = (bool)printer["WorkOffline"];
if (workOffline) return false;
int statusAsInteger = Int32.Parse(status.ToString());
switch (statusAsInteger)
{
case 3: //Idle
case 4: //Printing
case 5: //Warming up
case 6: //Stopped printing
return true;
default:
return false;
}
}
public static ManagementObjectCollection GetDefaultPrinters()
{
var printerSearcher =
new ManagementObjectSearcher(
"SELECT * FROM Win32_Printer where Default = true"
);
return printerSearcher.Get();
}
}
Now you can combine this with standard WinForms System.Drawing.Printing code:
//in a function, far far away from any button click handler :P
foreach(var printer in PrinterUtility.GetDefaultPrinters())
{
if (printer.IsOnline())
{
var pDoc = new PrintDocument(); //or get from PrintDialog
pDoc.PrinterSettings.PrinterName = printer["Name"].ToString();
if (pDoc.PrinterSettings.IsValid) //just check WMI didn't tell fibs about the name
{
//do printy things
}
}
}
Hope this helps