【WPF.NET开发】远程调查打印机的状态

本文内容

在大中型公司,在任何给定时间里,都可能发生由于卡纸、纸张用完或某些其他有问题而导致多台打印机无法工作的情况。 Microsoft .NET Framework 的 API 中公开的一组丰富的打印机属性提供一种方法,用于快速调查打印机状态。

示例

以下是创建此类实用程序的主要步骤。

  1. 获取所有打印服务器的列表。

  2. 循环访问服务器以查询其打印队列。

  3. 在每一轮服务器循环访问过程中,循环访问所有服务器的队列并读取每个属性,这些属性可能指示队列当前不在工作。

以下代码是一系列代码段。 为简单起见,本示例假定存在通过 CRLF 分隔的打印服务器列表。 变量 fileOfPrintServers 是该文件的 StreamReader 对象。 由于每个服务器名称是在单独的一行上,因此对 ReadLine 的任何调用将获取下一服务器的名称并将 StreamReader 的光标移动到下一行的开头。

在外部循环中,代码会创建最新打印服务器的 PrintServer 对象,并指定应用程序需具有服务器的管理权限。

 备注

如果有很多服务器,可以通过使用 PrintServer(String, String[], PrintSystemDesiredAccess) 构造函数来提高性能,这些构造函数仅初始化需要的属性。

然后,该示例使用 GetPrintQueues 来创建所有服务器队列的集合,并开始对其进行循环访问。 此内部循环包含一个分支结构,该结构对应于检查打印机状态的两种方法:

  • 可读取类型为 PrintQueueStatus 的 QueueStatus 属性的标记。

  • 可以读取每个相关属性,例如 IsOutOfPaper 和 IsPaperJammed。

此示例会演示这两种方法,系统会预先提示用户要使用哪种方法,且如果用户想要使用 QueueStatus 属性的标志,可回复“y”。 请参阅以下有关这两种方法的详细信息。

最后,会向用户显示结果。

// Survey queue status for every queue on every print server
String line;
String statusReport = "\n\nAny problem states are indicated below:\n\n";
while ((line = fileOfPrintServers.ReadLine()) != null)
 {
     PrintServer myPS = new PrintServer(line, PrintSystemDesiredAccess.AdministrateServer);
     PrintQueueCollection myPrintQueues = myPS.GetPrintQueues();
     statusReport = statusReport + "\n" + line;
     foreach (PrintQueue pq in myPrintQueues)
     {
         pq.Refresh();
         statusReport = statusReport + "\n\t" + pq.Name + ":";
         if (useAttributesResponse == "y")
         {
             TroubleSpotter.SpotTroubleUsingQueueAttributes(ref statusReport, pq);
             // TroubleSpotter class is defined in the complete example.
         }
         else
         {
             TroubleSpotter.SpotTroubleUsingProperties(ref statusReport, pq);
         }
     }// end for each print queue
 }// end while list of print servers is not yet exhausted

fileOfPrintServers.Close();
Console.WriteLine(statusReport);
Console.WriteLine("\nPress Return to continue.");
Console.ReadLine();

若要使用 QueueStatus 属性的标志检查打印机状态,请检查每个相关标志以查看是否对其进行了设置。 检查是否在一组位标志中设置了一个位的标准方法是执行一个逻辑 AND 运算,其中将该组标志作为一个操作数,将标志本身作为另一操作数。 由于该标志本身仅设置一个位,因此逻辑 AND 的结果至多为设置了该相同位。 若要查明事实是否如此,只需将逻辑 AND 的结果与标志本身进行比较。 

对于已设置了其位的各个特性,代码会将一条通知添加到将向用户显示的最终报告中。 (下面会讨论代码结束时调用的 ReportAvailabilityAtThisTime 方法。)

// Check for possible trouble states of a printer using the flags of the QueueStatus property
internal static void SpotTroubleUsingQueueAttributes(ref String statusReport, PrintQueue pq)
{
    if ((pq.QueueStatus & PrintQueueStatus.PaperProblem) == PrintQueueStatus.PaperProblem)
    {
        statusReport = statusReport + "Has a paper problem. ";
    }
    if ((pq.QueueStatus & PrintQueueStatus.NoToner) == PrintQueueStatus.NoToner)
    {
        statusReport = statusReport + "Is out of toner. ";
    }
    if ((pq.QueueStatus & PrintQueueStatus.DoorOpen) == PrintQueueStatus.DoorOpen)
    {
        statusReport = statusReport + "Has an open door. ";
    }
    if ((pq.QueueStatus & PrintQueueStatus.Error) == PrintQueueStatus.Error)
    {
        statusReport = statusReport + "Is in an error state. ";
    }
    if ((pq.QueueStatus & PrintQueueStatus.NotAvailable) == PrintQueueStatus.NotAvailable)
    {
        statusReport = statusReport + "Is not available. ";
    }
    if ((pq.QueueStatus & PrintQueueStatus.Offline) == PrintQueueStatus.Offline)
    {
        statusReport = statusReport + "Is off line. ";
    }
    if ((pq.QueueStatus & PrintQueueStatus.OutOfMemory) == PrintQueueStatus.OutOfMemory)
    {
        statusReport = statusReport + "Is out of memory. ";
    }
    if ((pq.QueueStatus & PrintQueueStatus.PaperOut) == PrintQueueStatus.PaperOut)
    {
        statusReport = statusReport + "Is out of paper. ";
    }
    if ((pq.QueueStatus & PrintQueueStatus.OutputBinFull) == PrintQueueStatus.OutputBinFull)
    {
        statusReport = statusReport + "Has a full output bin. ";
    }
    if ((pq.QueueStatus & PrintQueueStatus.PaperJam) == PrintQueueStatus.PaperJam)
    {
        statusReport = statusReport + "Has a paper jam. ";
    }
    if ((pq.QueueStatus & PrintQueueStatus.Paused) == PrintQueueStatus.Paused)
    {
        statusReport = statusReport + "Is paused. ";
    }
    if ((pq.QueueStatus & PrintQueueStatus.TonerLow) == PrintQueueStatus.TonerLow)
    {
        statusReport = statusReport + "Is low on toner. ";
    }
    if ((pq.QueueStatus & PrintQueueStatus.UserIntervention) == PrintQueueStatus.UserIntervention)
    {
        statusReport = statusReport + "Needs user intervention. ";
    }

    // Check if queue is even available at this time of day
    // The method below is defined in the complete example.
    ReportAvailabilityAtThisTime(ref statusReport, pq);
}

若要使用各个属性检查打印机状态,只需读取各个属性,并将注释添加到最终报告,如果属性为 true,将向用户显示最终报告。 (下面会讨论代码结束时调用的 ReportAvailabilityAtThisTime 方法。)

// Check for possible trouble states of a printer using its properties
internal static void SpotTroubleUsingProperties(ref String statusReport, PrintQueue pq)
{
    if (pq.HasPaperProblem)
    {
        statusReport = statusReport + "Has a paper problem. ";
    }
    if (!(pq.HasToner))
    {
        statusReport = statusReport + "Is out of toner. ";
    }
    if (pq.IsDoorOpened)
    {
        statusReport = statusReport + "Has an open door. ";
    }
    if (pq.IsInError)
    {
        statusReport = statusReport + "Is in an error state. ";
    }
    if (pq.IsNotAvailable)
    {
        statusReport = statusReport + "Is not available. ";
    }
    if (pq.IsOffline)
    {
        statusReport = statusReport + "Is off line. ";
    }
    if (pq.IsOutOfMemory)
    {
        statusReport = statusReport + "Is out of memory. ";
    }
    if (pq.IsOutOfPaper)
    {
        statusReport = statusReport + "Is out of paper. ";
    }
    if (pq.IsOutputBinFull)
    {
        statusReport = statusReport + "Has a full output bin. ";
    }
    if (pq.IsPaperJammed)
    {
        statusReport = statusReport + "Has a paper jam. ";
    }
    if (pq.IsPaused)
    {
        statusReport = statusReport + "Is paused. ";
    }
    if (pq.IsTonerLow)
    {
        statusReport = statusReport + "Is low on toner. ";
    }
    if (pq.NeedUserIntervention)
    {
        statusReport = statusReport + "Needs user intervention. ";
    }

    // Check if queue is even available at this time of day
    // The following method is defined in the complete example.
    ReportAvailabilityAtThisTime(ref statusReport, pq);
}//end SpotTroubleUsingProperties

创建了 ReportAvailabilityAtThisTime 方法,以应对需要确定队列在一天的当前时间是否可用的情况。

如果 StartTimeOfDay 和 UntilTimeOfDay 属性相等,该方法将不会执行任何操作;因为在这种情况下,打印机始终可用。 如果它们不同,则该方法将获取当前时间,该时间必须随后转换为午夜过后的总分钟数,因为 StartTimeOfDay 和 UntilTimeOfDay 属性是表示午夜后分钟数的 Int32,而不是 DateTime 对象。 最后,该方法会检查当前时间是否介于开始时间和“截至”时间之间。

private static void ReportAvailabilityAtThisTime(ref String statusReport, PrintQueue pq)
{
    if (pq.StartTimeOfDay != pq.UntilTimeOfDay) // If the printer is not available 24 hours a day
    {
DateTime utcNow = DateTime.UtcNow;
Int32 utcNowAsMinutesAfterMidnight = (utcNow.TimeOfDay.Hours * 60) + utcNow.TimeOfDay.Minutes;

        // If now is not within the range of available times . . .
        if (!((pq.StartTimeOfDay < utcNowAsMinutesAfterMidnight)
           &&
           (utcNowAsMinutesAfterMidnight < pq.UntilTimeOfDay)))
        {
            statusReport = statusReport + " Is not available at this time of day. ";
        }
    }
}

你可能感兴趣的:(WPF.NET,专栏,wpf,c#,.net)