Есть ли способ .NET перечислить все доступные сетевые принтеры? - PullRequest
13 голосов
/ 19 июня 2009

Существует ли простой способ перечисления всех видимых сетевых принтеров в .NET? В настоящее время я показываю PrintDialog, чтобы позволить пользователю выбрать принтер. Проблема в том, что локальные принтеры также отображаются (вместе с XPS Document Writer и т. П.). Если я могу сам перечислять сетевые принтеры, я могу показать собственный диалог только с этими принтерами.

Спасибо !!

Ответы [ 5 ]

16 голосов
/ 31 августа 2011
  • Получить принтер по умолчанию из LocalPrintServer.DefaultPrintQueue
  • Получить установленные принтеры (с точки зрения пользователя) из PrinterSettings.InstalledPrinters
  • Перечислите по списку:
  • Любой принтер, начинающийся с \\, является сетевым принтером - поэтому получите очередь с new PrintServer("\\UNCPATH").GetPrintQueue("QueueName")
  • Любой принтер, не начинающийся с \\, является локальным принтером, поэтому получите его с LocalPrintServer.GetQueue("Name")
  • Вы можете узнать, какое значение по умолчанию, сравнив свойство FullName.

Примечание: сетевой принтер может быть принтером по умолчанию с LocalPrintServer.DefaultPrintQueue, но не может отображаться в 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);
12 голосов
/ 19 августа 2009

с использованием нового API System.Printing

using (var printServer = new PrintServer(string.Format(@"\\{0}", PrinterServerName)))
{
    foreach (var queue in printServer.GetPrintQueues())
    {
        if (!queue.IsShared)
        {
            continue;
        }
        Debug.WriteLine(queue.Name);
     }
 }
9 голосов
/ 19 июня 2009

нашел этот код здесь

 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]);
                    }
                }
            }

        }

Обновление:

«Эта функция API может перечислять все сетевые ресурсы, включая серверы, рабочие станции, принтеры, общие ресурсы, удаленные каталоги и т. Д.»

http://www.planet -source-code.com / VB / скрипты / ShowCode.asp? TxtCodeId = 741 & lngWId = 10

2 голосов
/ 13 ноября 2016

В другом посте (https://stackoverflow.com/a/30758129/6513653) по этому поводу Скотт Чемберлен сказал: «Я не верю, что в .NET есть что-то, что может сделать это, вам нужно будет сделать собственный вызов». После попытки все возможные ресурсы .NET, я думаю, что он прав. Итак, я начал исследовать, как диалог ADD PRINTER выполняет поиск. Используя Wireshark, я обнаружил, что ADD PRINTER отправляет по крайней мере два типа пакетов на все хосты в локальной сети: два запроса http / xml на порт 3911 и три запроса SNMP. enter image description here Первым запросом SNMP является get-next 1.3.6.1.2.1.43, который представляет собой Printer-MIB. Вторым является get 1.3.6.1.4.1.2699.1.2.1.2.1.1.3, который представляет собой pmPrinterIEEE1284DeviceId PRINTER-PORT-MONITOR-MIB. Это наиболее интересно, потому что именно там ADD PRINTER берет имя принтера. Третий - это get 1.3.6.1.2.1.1.1.0, который является sysDescr системы SNMP MIB-2. Я действительно считаю, что второго запроса SNMP достаточно, чтобы найти большинство сетевых принтеров в локальной сети, поэтому я сделал этот код. Он работает для Windows Form Application и зависит от SnmpSharpNet.

Edit: я использую ARP Ping вместо обычного Ping для поиска активных хостов в сети. Ссылка на пример проекта: ListNetworks C # Project

2 голосов
/ 19 июня 2009

PrinterSettiings.InstalledPrinters должен дать вам нужную коллекцию

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...