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

后端 未结 6 580
悲&欢浪女
悲&欢浪女 2020-11-28 09:16

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

相关标签:
6条回答
  • 2020-11-28 09:25

    PrinterSettiings.InstalledPrinters should give you the collection you want

    0 讨论(0)
  • 2020-11-28 09:40

    using the new System.Printing API

    using (var printServer = new PrintServer(string.Format(@"\\{0}", PrinterServerName)))
    {
        foreach (var queue in printServer.GetPrintQueues())
        {
            if (!queue.IsShared)
            {
                continue;
            }
            Debug.WriteLine(queue.Name);
         }
     }
    
    0 讨论(0)
  • 2020-11-28 09:43
    • 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);
    
    0 讨论(0)
  • 2020-11-28 09:44

    found this code here

     private void btnGetPrinters_Click(object sender, EventArgs e)
            {
    // Use the ObjectQuery to get the list of configured printers
                System.Management.ObjectQuery oquery =
                    new System.Management.ObjectQuery("SELECT * FROM Win32_Printer");
    
                System.Management.ManagementObjectSearcher mosearcher =
                    new System.Management.ManagementObjectSearcher(oquery);
    
                System.Management.ManagementObjectCollection moc = mosearcher.Get();
    
                foreach (ManagementObject mo in moc)
                {
                    System.Management.PropertyDataCollection pdc = mo.Properties;
                    foreach (System.Management.PropertyData pd in pdc)
                    {
                        if ((bool)mo["Network"])
                        {
                            cmbPrinters.Items.Add(mo[pd.Name]);
                        }
                    }
                }
    
            }
    

    Update:

    "This API function can enumerate all network resources, including servers, workstations, printers, shares, remote directories etc."

    http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=741&lngWId=10

    0 讨论(0)
  • 2020-11-28 09:44

    In another post(https://stackoverflow.com/a/30758129/6513653) relationed to this one, Scott Chamberlain said "I do not believe there is anything in .NET that can do this, you will need to make a native call". After to try all the possible .NET resource, I think he is right. So, I started to investigate how ADD PRINTER dialog does its search. Using Wireshark, I found out that ADD PRINTER send at least two types of packages to all hosts in local network: two http/xml request to 3911 port and three SNMP requests. The first SNMP request is a get-next 1.3.6.1.2.1.43, which is Printer-MIB. The second one, is a get 1.3.6.1.4.1.2699.1.2.1.2.1.1.3 which is pmPrinterIEEE1284DeviceId of PRINTER-PORT-MONITOR-MIB. This is the most interesting because is where ADD PRINTER takes printer name. The third is a get 1.3.6.1.2.1.1.1.0, which is sysDescr of SNMP MIB-2 System. I do believe that the second SNMP request is enough to find most of network printers in local network, so I did this code. It works for Windows Form Application and it depends on SnmpSharpNet.

    Edit: I'm using ARP Ping instead normal Ping to search active hosts in network. Link for an example project: ListNetworks C# Project

    0 讨论(0)
  • 2020-11-28 09:46

    Note that if you're working over RDP it seems to complicate this because it looks like it just exports everything on the host as a local printer.

    Which is then a problem if you're expecting it to work the same way when not on RDP.

    0 讨论(0)
提交回复
热议问题