如何确定使用WMI连接的打印机 [英] How to Determine Which Printers are Connected using WMI

查看:96
本文介绍了如何确定使用WMI连接的打印机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直试图找到一种方法来确定哪些已安装的打印机是已连接"的.经过一番谷歌搜索后,我认为我必须潜入WMI.

I've been trying to find a way to figure out which installed printers are 'connected'. After some Googling I figured I had to dive into WMI.

所以我建立了这个测试:

So I've built this test:

// Struct to store printer data in.
public struct MyPrinter 
{ 
    public string Availability; 
    public string ExtendedPrinterStatus; 
    public string Name; 
    public string PrinterStatus; 
    public string Status; 
    public string StatusInfo; 

    public MyPrinter(string a, string eps, string n, string ps, string s, string si) 
    { 
        Availability = a; 
        ExtendedPrinterStatus = eps; 
        Name = n; 
        PrinterStatus = ps; 
        Status = s; 
        StatusInfo = si; 
    } 
}


var installedPrinters = new string[numPrinters];
PrinterSettings.InstalledPrinters.CopyTo(installedPrinters, 0);

var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Printer"); 
var data = new List<MyPrinter>(); 

foreach (var printer in searcher.Get()) 
{ 
    if (installedPrinters.Contains(printer["Name"].ToString()))
    {
        var availability = (printer["Availability"] ?? "").ToString(); 
        var extendedPrinterStatus = (printer["ExtendedPrinterStatus"] ?? "").ToString(); 
        var name = (printer["Name"] ?? "").ToString(); 
        var printerStatus = (printer["PrinterStatus"] ?? "").ToString(); 
        var status = (printer["Status"] ?? "").ToString(); 
        var statusInfo = (printer["StatusInfo"] ?? "").ToString(); 

        data.Add(new MyPrinter(availability, extendedPrinterStatus, name, printerStatus, status, statusInfo)); 
    }
}

我有6台打印机,其中2台是网络打印机.我在连接所有打印机的情况下运行了此程序,所有结果如下所示:

I have 6 printers from which 2 are network printers. I've run this with all printers connected and all results looked like this:

Availability = "" // printer["Availability"] = null
ExtendedPrinterStatus = "2" // 2 = Unknown
Name = "{printer name here}"
PrinterStatus = "3" // 3 = Idle
Status = "Unknown"
StatusInfo = "" // Null

因此,打印机之间的唯一区别是名称.我再次运行了脚本,但是这次我断开了笔记本电脑与网络的连接.因此,在这种情况下,其中2台打印机不再连接.

So the only difference between the printers is the name. I ran the script again but this time I disconnected my laptop from the network. So 2 of the printers were not connected anymore in this case.

(对我而言)奇怪的是,结果完全相同.

The strange thing (for me) is, the results were exactly the same.

我运行此测试的原因是为了弄清楚我的案子需要使用哪个字段.

The reason I ran this test is, to figure out which field I'd need to use for my case.

因此,最后,我还无法弄清楚如何确定是否连接了打印机.因此,我想要的是一种找出C#中已安装+连接的打印机的方法.如果有一种方法可以不使用WMI类,那么我也可以,只要它可以工作即可.

So at the end, I have not been able to figure out how to figure out if a printer is connected or not. So what I'd like, is a way to figure out the installed + connected printers in C#. If there is a way to do it without the use of WMI classes, that's also fine by me, as long as it works.

推荐答案

我和一位同事尝试了很多方法来找到解决方案,我们认为这是可行的:

Me and a colleague have tried lots of stuff to find a solution for this and we figured this worked:

private string[] GetAvailablePrinters()
{
    var installedPrinters = new string[PrinterSettings.InstalledPrinters.Count];
    PrinterSettings.InstalledPrinters.CopyTo(installedPrinters, 0);

    var printers = new List<string>();
    var printServers = new List<string>();
    var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Printer");

    foreach (var printer in searcher.Get())
    {
        var serverName = @"\\" + printer["SystemName"].ToString().TrimStart('\\');
        if (!printServers.Contains(serverName))
            printServers.Add(serverName);
    }

    foreach (var printServer in printServers)
    {
        var server = new PrintServer(printServer);
        try
        {
            var queues = server.GetPrintQueues();
            printers.AddRange(queues.Select(q => q.Name));
        }
        catch (Exception)
        {
            // Handle exception correctly
        }
    }

    return printers.ToArray();
}

诀窍是,当打印服务器不可用时,GetPrintQueues将引发一些特定的异常.通过仅添加不会引发此类异常的打印机,我们可以获得所有已连接打印机的列表.这不会检查打印机是否已打开/关闭,因为这实际上无关紧要.如果将其关闭,则文档将仅放置在打印队列中,以后可以打印.

The trick is that when a printserver is not available, GetPrintQueues will throw some specific exception. By only adding the printers that don't throw such an exception, we get a list of all the connected printers. This doesn't check if a printer is turned on/off because that actually doesn't matter. If it is turned off, the document will just be placed in the print queue and it can be printed later on.

我希望这可以帮助遇到此问题的其他人.

I hope this helps others who bump into this problem.

旁注:我之所以决定不捕获该特定异常,是因为我必须为该异常引用一个dll.

Sidenote: The reason I decided not to catch that specific exception, is because I would have to reference a dll just for that exception.

这篇关于如何确定使用WMI连接的打印机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆