2012-11-08 35 views
1

我一直在試圖找出一種方法來找出哪些已安裝的打印機「連接」。谷歌搜索後,我想我不得不潛入WMI。如何確定使用WMI連接哪些打印機

所以我已經建立了這個測試:

// 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是網絡打印機。我已經連接所有打印機運行這個與所有的結果是這樣的:

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

所以打印機之間的唯一區別是名稱。 我再次運行腳本,但這次我斷開我的筆記本電腦從網絡。因此,在這種情況下,2臺打印機不再連接。

奇怪的事情(對我來說)是,結果完全一樣。

我跑這個測試的原因是爲了弄清楚哪個字段我需要用於我的情況。

所以最後,我一直無法弄清楚如何確定打印機是否連接。 所以我想要的是一種找出C#中已安裝的+連接的打印機的方法。如果有一種方法可以在不使用WMI類的情況下做到這一點,那麼只要它有效,我也很好。

+0

看起來是一樣的這個問題:http://stackoverflow.com/questions/2327763/is-there-a-possibility-to-differ-virtual-printer-from-physical-one?rq=1 – Lizz

+0

不是。這是關於虛擬打印機,而這是關於連接的打印機。 – MrSoundless

回答

4

我和同事都試過很多的東西找到了一個解決方案,我們想通這工作:

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會拋出一些特定的異常。通過只添加不引發這種異常的打印機,我們可以獲得所有連接打印機的列表。這並不檢查打印機是否打開/關閉,因爲這實際上並不重要。如果它被關閉,文檔將被放置在打印隊列中,並且可以稍後打印。

我希望這可以幫助那些遇到這個問題的人。

旁註: 我之所以決定不以捕獲特定的異常,是因爲我不得不引用一個dll只是該異常。

+0

這不是一個很好的理由來忽略異常。非常不好的習慣進入。 –

+0

我從未說過我'忽略'異常! – MrSoundless

+0

我指的是空的'Catch(Exception)'塊。 –

相關問題