【问题标题】:Is there a .NET way to enumerate all available network printers?是否有一种 .NET 方法来枚举所有可用的网络打印机?
【发布时间】:2009-06-19 13:38:09
【问题描述】:

是否有一种简单的方法来枚举 .NET 中所有可见的网络打印机?目前,我正在展示 PrintDialog 以允许用户选择打印机。问题是,本地打印机也会显示(以及 XPS Document Writer 等)。如果我可以自己枚举网络打印机,我可以只显示这些打印机的自定义对话框。

谢谢!!

【问题讨论】:

  • AvailablePrinterInfo 在哪个命名空间中?getting as Error 找不到类型或命名空间名称“AvailablePrinterInfo”(您是否缺少 using 指令或程序集引用

标签: c# .net network-printers


【解决方案1】:
  • 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);

【讨论】:

  • 谢谢西蒙 - 非常有用。
  • 每次我对此表示赞同时,我都会想“真是一团糟!”。很高兴它有帮助 - 但希望现在有更好的方法!
【解决方案2】:

使用新的 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);
     }
 }

【讨论】:

  • 这应该是公认的答案。直截了当。
【解决方案3】:

找到此代码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]);
                    }
                }
            }

        }

更新:

"此 API 函数可以枚举所有网络资源,包括服务器、工作站、打印机、共享、远程目录等。"

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

【讨论】:

  • +1 谢谢!我可以只列举已安装的网络打印机的名称,只需对该代码进行一些小调整。现在,您知道是否可以使用类似技术枚举所有 VISIBLE 网络打印机(不仅仅是已安装的)。
  • 试试这篇文章:planet-source-code.com/vb/scripts/…“这个API函数可以枚举所有的网络资源,包括服务器、工作站、打印机、共享、远程目录等。”希望对你有帮助,干杯
  • 最后一条语句出现空异常。
  • 只是想补充一点,据我所知,这不再有效。看起来 ObjectQuery 已经不存在了。
【解决方案4】:

PrinterSettiings.InstalledPrinters 应该会给你你想要的收藏

【讨论】:

  • PrinterSettings.InstalledPrinters 仍然显示非网络打印机,以及文档打印机(PDF Writer、XPS Document Writer 等)。
【解决方案5】:

在与此相关的另一篇文章 (https://stackoverflow.com/a/30758129/6513653) 中,Scott Chamberlain 说:“我不相信 .NET 中有任何东西可以做到这一点,您需要进行本地调用”。在尝试了所有可能的 .NET 资源之后,我认为他是对的。 所以,我开始研究 ADD PRINTER 对话框是如何进行搜索的。使用 Wireshark,我发现 ADD PRINTER 向本地网络中的所有主机发送至少两种类型的包:两个 http/xml 请求到 3911 端口和三个 SNMP 请求。 第一个 SNMP 请求是 get-next 1.3.6.1.2.1.43,即 Printer-MIB。第二个,是获取 1.3.6.1.4.1.2699.1.2.1.2.1.1.3,它是 PRINTER-PORT-MONITOR-MIB 的 pmPrinterIEEE1284DeviceId。这是最有趣的,因为这是 ADD PRINTER 获取打印机名称的地方。第三个是get 1.3.6.1.2.1.1.1.0,就是SNMP MIB-2 System的sysDescr。 我相信第二个 SNMP 请求足以找到本地网络中的大多数网络打印机,所以我做了这个代码。它适用于 Windows 窗体应用程序,它依赖于 SnmpSharpNet。

编辑:我使用 ARP Ping 而不是普通 Ping 来搜索网络中的活动主机。示例项目链接:ListNetworks C# Project

【讨论】:

    【解决方案6】:

    请注意,如果您正在使用 RDP,这似乎会变得复杂,因为它看起来只是将主机上的所有内容都导出为本地打印机。

    如果您希望它在不使用 RDP 时以相同的方式工作,那么这将是一个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-02
      • 2020-03-18
      • 2011-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多