Is there a .NET way to enumerate all available network printers?

Mark Carpenter picture Mark Carpenter · Jun 19, 2009 · Viewed 23.7k times · Source

Is there a straightforward way to enumerate all visible network printers in .NET? Currently, I'm showing the PrintDialog to allow the user to select a printer. The problem with that is, local printers are displayed as well (along with XPS Document Writer and the like). If I can enumerate network printers myself, I can show a custom dialog with just those printers.

Thanks!!

Answer

Simon_Weaver picture Simon_Weaver · Aug 31, 2011
  • Get the default printer from LocalPrintServer.DefaultPrintQueue
  • Get the installed printers (from user's perspective) from PrinterSettings.InstalledPrinters
  • Enumerate through the list:
  • Any printer beginning with \\ is a network printer - so get the queue with new PrintServer("\\UNCPATH").GetPrintQueue("QueueName")
  • Any printer not beginning with \\ is a local printer so get it with LocalPrintServer.GetQueue("Name")
  • You can see which is default by comparing FullName property.

Note: a network printer can be the default printer from LocalPrintServer.DefaultPrintQueue, but not appear in LocalPrintServer.GetPrintQueues()

    // get available printers
    LocalPrintServer printServer = new LocalPrintServer();
    PrintQueue defaultPrintQueue = printServer.DefaultPrintQueue;

    // get all printers installed (from the users perspective)he t
    var printerNames = PrinterSettings.InstalledPrinters;
    var availablePrinters = printerNames.Cast<string>().Select(printerName => 
    {
        var match = Regex.Match(printerName, @"(?<machine>\\\\.*?)\\(?<queue>.*)");
        PrintQueue queue;
        if (match.Success)
        {
            queue = new PrintServer(match.Groups["machine"].Value).GetPrintQueue(match.Groups["queue"].Value);
        }
        else
        {
            queue = printServer.GetPrintQueue(printerName);
        }

        var capabilities = queue.GetPrintCapabilities();
        return new AvailablePrinterInfo()
        {
            Name = printerName,
            Default = queue.FullName == defaultPrintQueue.FullName,
            Duplex = capabilities.DuplexingCapability.Contains(Duplexing.TwoSidedLongEdge),
            Color = capabilities.OutputColorCapability.Contains(OutputColor.Color)
        };
    }).ToArray();

    DefaultPrinter = AvailablePrinters.SingleOrDefault(x => x.Default);