1

インストールされているどのプリンターが「接続」されているかを把握する方法を見つけようとしています。グーグルで調べた後、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 クラスを使用せずにそれを行う方法があれば、それが機能する限り、それも問題ありません。

4

1 に答える 1

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 を参照する必要があるためです。

于 2012-11-12T07:56:41.250 に答える