15

I am enumerating printers connected in the PC. I done it using C# System.Printing namespace. It works well. But mostly it shows software printers like Microsoft XPS Document writer,Microsoft Fax etc. I would like to know is it possible to remove these ssoftware printers from enumeration. The code I have done is show below :

PrintQueue printQueue = null;

LocalPrintServer localPrintServer = new LocalPrintServer();

// Retrieving collection of local printer on user machine
PrintQueueCollection localPrinterCollection =
    localPrintServer.GetPrintQueues(new[] { EnumeratedPrintQueueTypes.Local,
                                            EnumeratedPrintQueueTypes.Connections });

System.Collections.IEnumerator localPrinterEnumerator =
    localPrinterCollection.GetEnumerator();

while (localPrinterEnumerator.MoveNext())
{
    // Get PrintQueue from first available printer
    printQueue = (PrintQueue)localPrinterEnumerator.Current;

    if (!printQueue.IsOffline)
    {
        MessageBox.Show(printQueue.FullName.ToString());
        string s = "Printer found " + printQueue.FullName.ToString();
        listBox1.Items.Add(s);
    }
    else
    {
        // No printer exist, return null PrintTicket 
        // return null;
    }
}
John Willemse
  • 6,608
  • 7
  • 31
  • 45
Zigma
  • 529
  • 6
  • 37

4 Answers4

12

The key to distinguishing a real printer from a virtual printer is the port the printer is using. Real printers use hardware ports such as LPT1: or USB ports. Virtual printers use software-driven ports.

The complication will be network printers. It won't be easy determining if a network printer is using a hardware port.

I know this isn't a great answer but you've posed a very difficult question. I hope it gets your started in the right direction.

Carey Gregory
  • 6,836
  • 2
  • 26
  • 47
  • 1
    I've given this a lot of thought over the last few days, and I think I know the Windows printing subsystem as well as anyone outside of Microsoft, and... well, I'm afraid I don't think there is a way to reliably distinguish between a hardware and a virtual printer in all cases. I could give you a "usually right" solution, but I don't think an "always right" solution is possible. Sorry. :-( – Carey Gregory May 29 '13 at 06:33
6

The only way I found is to compare the name of desired printer with the one we are getting.

Victor Zakharov
  • 25,801
  • 18
  • 85
  • 151
Zigma
  • 529
  • 6
  • 37
3

Few observations:

  1. In the Properties window the Device Settings Page is available ONLY for the Real Printers and NOT for the Virtual Printers. And most of these values are available in printQueue.UserPrintTicket property

  2. printQueue.QueuePort.Name contains an IP address appended with or without the port name. ex: "20.120.12.22_1" or "20.120.12.22" for Real Printers

enter image description here

jacob aloysious
  • 2,547
  • 15
  • 16
2

You can use the Print Spooler API to manage printers and printjobs. Specially the EnumPrinters function might be useful for you. You can grab the c# wrapper from Pinvoke.net

dsfgsho
  • 2,731
  • 2
  • 22
  • 39