方法 : プリンターのステータスをリモート操作で調査する

中企業および大企業では、任意の時点において、紙詰まりや用紙切れなどの問題が発生したために動作していないプリンターが複数存在する場合があります。 Microsoft .NET Framework の APIs で公開されているさまざまなプリンター プロパティには、プリンターの状態を迅速に調査する手段が用意されています。

使用例

このようなユーティリティを作成する主な手順は次のとおりです。

  1. すべてのプリント サーバーのリストを取得します。

  2. 印刷キューを照会するためにサーバーをループします。

  3. サーバー ループの各パス内で、すべてのサーバーのキューをループし、キューが現在動作していないことを示している各プロパティを読み取ります。

一連のスニペットを次のコードに示します。 この例では、単純化のため、CRLF で区切られたプリント サーバーのリストがあると想定します。 fileOfPrintServers 変数は、このファイルの StreamReader オブジェクトです。 各サーバー名はそれぞれ独自の行に含まれているため、ReadLine を呼び出すと、次のサーバーの名前が取得され、StreamReader のカーソルが次の行の先頭に移動します。

このコードは、外側のループ内で、最新のプリント サーバーの PrintServer オブジェクトを作成し、アプリケーションがサーバーに対する管理権限を持つことを指定します。

メモメモ

サーバーが多数存在する場合は、必要なプロパティのみを初期化する PrintServer(String, String[], PrintSystemDesiredAccess) コンストラクターを使用することで、パフォーマンスを向上させることができます。

この例では、次に GetPrintQueues を使用してサーバーのすべてのキューのコレクションを作成し、これらのキューのループを開始します。 この内側のループには、プリンターのステータスを確認する 2 つの方法に対応する分岐構造が含まれています。

この例では両方の方法を示すため、ユーザーは使用する方法に関して入力を求められ、QueueStatus プロパティのフラグを使用する場合は「y」と応答しています。 2 つの方法の詳細については、以下を参照してください。

最後に、結果をユーザーに表示します。

            ' Survey queue status for every queue on every print server
            Dim line As String
            Dim statusReport As String = vbLf & vbLf & "Any problem states are indicated below:" & vbLf & vbLf
            line = fileOfPrintServers.ReadLine()
            Do While line IsNot Nothing
                 Dim myPS As New PrintServer(line, PrintSystemDesiredAccess.AdministrateServer)
                 Dim myPrintQueues As PrintQueueCollection = myPS.GetPrintQueues()
                 statusReport = statusReport & vbLf & line
                 For Each pq As PrintQueue In myPrintQueues
                     pq.Refresh()
                     statusReport = statusReport & vbLf & vbTab & pq.Name & ":"
                     If useAttributesResponse = "y" Then
                         TroubleSpotter.SpotTroubleUsingQueueAttributes(statusReport, pq)
                         ' TroubleSpotter class is defined in the complete example.
                     Else
                         TroubleSpotter.SpotTroubleUsingProperties(statusReport, pq)
                     End If

                 Next pq ' end for each print queue

                line = fileOfPrintServers.ReadLine()
            Loop ' end while list of print servers is not yet exhausted

            fileOfPrintServers.Close()
            Console.WriteLine(statusReport)
            Console.WriteLine(vbLf & "Press Return to continue.")
            Console.ReadLine()

// 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();

// Survey queue status for every queue on every print server
System::String^ line;
System::String^ statusReport = "\n\nAny problem states are indicated below:\n\n";
while ((line = fileOfPrintServers->ReadLine()) != nullptr)
{
   System::Printing::PrintServer^ myPS = gcnew System::Printing::PrintServer(line, PrintSystemDesiredAccess::AdministrateServer);
   System::Printing::PrintQueueCollection^ myPrintQueues = myPS->GetPrintQueues();
   statusReport = statusReport + "\n" + line;
   for each (System::Printing::PrintQueue^ pq in myPrintQueues)
   {
      pq->Refresh();
      statusReport = statusReport + "\n\t" + pq->Name + ":";
      if (useAttributesResponse == "y")
      {
         TroubleSpotter::SpotTroubleUsingQueueAttributes(statusReport, pq);
         // TroubleSpotter class is defined in the complete example.
      } else
      {
         TroubleSpotter::SpotTroubleUsingProperties(statusReport, pq);
      }
   }
}
fileOfPrintServers->Close();
Console::WriteLine(statusReport);
Console::WriteLine("\nPress Return to continue.");
Console::ReadLine();

QueueStatus プロパティのフラグを使用してプリンターのステータスを確認するには、各関連フラグが設定されているかどうかを確認します。 1 ビットがビット フラグ セットで設定されているかどうかを確認するには、通常、フラグ セットを 1 つのオペランドとし、フラグ自体をもう 1 つのオペランドとして、論理 AND 演算を行います。 フラグ自体には 1 ビットのみが設定されているため、論理 AND を実行すると、最大でもその同じビットが設定されます。 該当するかどうかを確認するには、論理 AND の結果とフラグ自体を比較します。 詳細については、PrintQueueStatus& 演算子 (C# リファレンス)、および FlagsAttribute のトピックを参照してください。

次のコードでは、ビットが設定されている属性ごとに、ユーザーに表示される最終レポートに警告を追加します (コードの最後で呼び出している ReportAvailabilityAtThisTime メソッドについては以下で説明します)。

        ' Check for possible trouble states of a printer using the flags of the QueueStatus property
        Friend Shared Sub SpotTroubleUsingQueueAttributes(ByRef statusReport As String, ByVal pq As PrintQueue)
            If (pq.QueueStatus And PrintQueueStatus.PaperProblem) = PrintQueueStatus.PaperProblem Then
                statusReport = statusReport & "Has a paper problem. "
            End If
            If (pq.QueueStatus And PrintQueueStatus.NoToner) = PrintQueueStatus.NoToner Then
                statusReport = statusReport & "Is out of toner. "
            End If
            If (pq.QueueStatus And PrintQueueStatus.DoorOpen) = PrintQueueStatus.DoorOpen Then
                statusReport = statusReport & "Has an open door. "
            End If
            If (pq.QueueStatus And PrintQueueStatus.Error) = PrintQueueStatus.Error Then
                statusReport = statusReport & "Is in an error state. "
            End If
            If (pq.QueueStatus And PrintQueueStatus.NotAvailable) = PrintQueueStatus.NotAvailable Then
                statusReport = statusReport & "Is not available. "
            End If
            If (pq.QueueStatus And PrintQueueStatus.Offline) = PrintQueueStatus.Offline Then
                statusReport = statusReport & "Is off line. "
            End If
            If (pq.QueueStatus And PrintQueueStatus.OutOfMemory) = PrintQueueStatus.OutOfMemory Then
                statusReport = statusReport & "Is out of memory. "
            End If
            If (pq.QueueStatus And PrintQueueStatus.PaperOut) = PrintQueueStatus.PaperOut Then
                statusReport = statusReport & "Is out of paper. "
            End If
            If (pq.QueueStatus And PrintQueueStatus.OutputBinFull) = PrintQueueStatus.OutputBinFull Then
                statusReport = statusReport & "Has a full output bin. "
            End If
            If (pq.QueueStatus And PrintQueueStatus.PaperJam) = PrintQueueStatus.PaperJam Then
                statusReport = statusReport & "Has a paper jam. "
            End If
            If (pq.QueueStatus And PrintQueueStatus.Paused) = PrintQueueStatus.Paused Then
                statusReport = statusReport & "Is paused. "
            End If
            If (pq.QueueStatus And PrintQueueStatus.TonerLow) = PrintQueueStatus.TonerLow Then
                statusReport = statusReport & "Is low on toner. "
            End If
            If (pq.QueueStatus And PrintQueueStatus.UserIntervention) = PrintQueueStatus.UserIntervention Then
                statusReport = statusReport & "Needs user intervention. "
            End If

            ' Check if queue is even available at this time of day
            ' The method below is defined in the complete example.
            ReportAvailabilityAtThisTime(statusReport, pq)
        End Sub
// 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);
}
internal: 
   // Check for possible trouble states of a printer using the flags of the QueueStatus property
   static void SpotTroubleUsingQueueAttributes (System::String^% statusReport, System::Printing::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(statusReport, pq);
   };

各プロパティを使用してプリンターのステータスを確認するには、各プロパティを読み取り、プロパティが true の場合にユーザーに表示される最終レポートに警告を追加するだけです (コードの最後で呼び出している ReportAvailabilityAtThisTime メソッドについては以下で説明します)。

        ' Check for possible trouble states of a printer using its properties
        Friend Shared Sub SpotTroubleUsingProperties(ByRef statusReport As String, ByVal pq As PrintQueue)
            If pq.HasPaperProblem Then
                statusReport = statusReport & "Has a paper problem. "
            End If
            If Not(pq.HasToner) Then
                statusReport = statusReport & "Is out of toner. "
            End If
            If pq.IsDoorOpened Then
                statusReport = statusReport & "Has an open door. "
            End If
            If pq.IsInError Then
                statusReport = statusReport & "Is in an error state. "
            End If
            If pq.IsNotAvailable Then
                statusReport = statusReport & "Is not available. "
            End If
            If pq.IsOffline Then
                statusReport = statusReport & "Is off line. "
            End If
            If pq.IsOutOfMemory Then
                statusReport = statusReport & "Is out of memory. "
            End If
            If pq.IsOutOfPaper Then
                statusReport = statusReport & "Is out of paper. "
            End If
            If pq.IsOutputBinFull Then
                statusReport = statusReport & "Has a full output bin. "
            End If
            If pq.IsPaperJammed Then
                statusReport = statusReport & "Has a paper jam. "
            End If
            If pq.IsPaused Then
                statusReport = statusReport & "Is paused. "
            End If
            If pq.IsTonerLow Then
                statusReport = statusReport & "Is low on toner. "
            End If
            If pq.NeedUserIntervention Then
                statusReport = statusReport & "Needs user intervention. "
            End If

            ' Check if queue is even available at this time of day
            ' The following method is defined in the complete example.
            ReportAvailabilityAtThisTime(statusReport, pq)

        End Sub 'end SpotTroubleUsingProperties
// 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
internal: 
   // Check for possible trouble states of a printer using its properties
   static void SpotTroubleUsingProperties (System::String^% statusReport, System::Printing::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(statusReport, pq);
   };

ReportAvailabilityAtThisTime メソッドは、現在の時刻にキューが使用可能かどうかを確認する必要がある場合に備えて作成されたものです。

StartTimeOfDay プロパティと UntilTimeOfDay プロパティが等しい場合、このメソッドは何も実行しません。なぜなら、その場合、プリンターは常に使用可能だからです。 それぞれのプロパティが異なる場合、このメソッドは現在の時刻を取得します。次に、この時刻を午前 0 時からの合計分数に変換する必要があります。これは、StartTimeOfDay プロパティと UntilTimeOfDay プロパティが DateTime オブジェクトではなく、午前 0 時以降の分数を表す Int32 であるためです。 最後に、このメソッドは、現在の時刻が開始時刻と "終了" 時刻の間であるかどうかを確認します。

        Private Shared Sub ReportAvailabilityAtThisTime(ByRef statusReport As String, ByVal pq As PrintQueue)
            If pq.StartTimeOfDay <> pq.UntilTimeOfDay Then ' If the printer is not available 24 hours a day
        Dim utcNow As Date = Date.UtcNow
        Dim utcNowAsMinutesAfterMidnight As Int32 = (utcNow.TimeOfDay.Hours * 60) + utcNow.TimeOfDay.Minutes

                ' If now is not within the range of available times . . .
                If Not((pq.StartTimeOfDay < utcNowAsMinutesAfterMidnight) AndAlso (utcNowAsMinutesAfterMidnight < pq.UntilTimeOfDay)) Then
                    statusReport = statusReport & " Is not available at this time of day. "
                End If
            End If
        End Sub
        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. ";
                }
            }
        }
private: 
   static void ReportAvailabilityAtThisTime (System::String^% statusReport, System::Printing::PrintQueue^ pq) 
   {
      if (pq->StartTimeOfDay != pq->UntilTimeOfDay)
      {
         System::DateTime utcNow = DateTime::UtcNow;
         System::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. ";
         }
      }
   };

参照

参照

StartTimeOfDay

UntilTimeOfDay

DateTime

PrintQueueStatus

& 演算子 (C# リファレンス)

FlagsAttribute

GetPrintQueues

PrintServer

LocalPrintServer

EnumeratedPrintQueueTypes

PrintQueue

概念

WPF のドキュメント

印刷の概要