Condividi tramite


Procedura: verificare lo stato delle stampanti da postazione remota

Nelle aziende di medie e grandi dimensioni può verificarsi in qualsiasi momento l'arresto di più stampanti a causa di fogli bloccati o di carta esaurita o di qualche altro imprevisto. La vasta gamma di proprietà delle stampanti esposta nelle APIs di Microsoft .NET Framework consente la rapida verifica dello stato delle stampanti.

Esempio

Di seguito vengono descritti i passaggi principali per la creazione di questo tipo di utilità.

  1. Ottenere un elenco di tutti i server di stampa.

  2. Scorrere i server per eseguire una query sulle relative code di stampa.

  3. In ogni passaggio del ciclo del server, scorrere tutte le code del server e leggere ciascuna proprietà che consenta di identificare la coda che non è in funzione.

Il codice riportato di seguito è costituito da una serie di frammenti. Per semplicità, nell'esempio si presuppone l'esistenza di un elenco di server di stampa delimitato da CRLF. La variabile fileOfPrintServers è un oggetto StreamReader per questo file. Poiché il nome di ciascun server si trova su una riga distinta, qualsiasi chiamata a ReadLine ottiene il nome del server successivo e determina lo spostamento del cursore di StreamReader all'inizio della riga successiva.

Nel ciclo esterno, il codice crea un oggetto PrintServer per l'ultimo server di stampa e specifica che l'applicazione deve disporre di diritti di amministrazione sul server.

NotaNota

Se i server sono numerosi, è possibile migliorare le prestazioni utilizzando i costruttori PrintServer(String, String[], PrintSystemDesiredAccess) che consentono di inizializzare soltanto le proprietà che saranno necessarie.

Nell'esempio viene quindi utilizzato GetPrintQueues per creare un insieme di tutte le code del server e iniziare a scorrerle. Il ciclo interno include una struttura con diramazioni, corrispondente alle due modalità di verifica dello stato di una stampante:

Nell'esempio vengono illustrati entrambi i metodi. All'utente è stato pertanto richiesto di scegliere il metodo da utilizzare e di rispondere con "y" per utilizzare i flag della proprietà QueueStatus. Per informazioni dettagliate relative ai due metodi vedere di seguito.

I risultati vengono infine presentati all'utente.

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

Per controllare lo stato delle stampanti utilizzando i flag della proprietà QueueStatus, esaminare ogni flag pertinente per verificare se è impostato. La modalità standard per verificare se in un set di flag di bit è stato impostato un determinato bit consiste nell'eseguire un'operazione di AND logico in cui un operando sia costituito dal set di flag e l'altro dal flag stesso. Dal momento che il flag stesso dispone di un solo bit impostato, il risultato dell'operazione di AND logico consisterà, al più, nell'impostazione dello stesso bit. Per verificare se il bit è impostato, confrontare il risultato dell'operazione di AND logico con il flag stesso. Per ulteriori informazioni, vedere PrintQueueStatus, Operatore & (Riferimenti per C#) e FlagsAttribute.

Per ciascun attributo in cui il bit è impostato, il codice aggiunge un avviso al report finale che sarà inviato all'utente. Il metodo ReportAvailabilityAtThisTime chiamato alla fine del codice viene illustrato di seguito.

        ' 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);
   };

Per controllare lo stato delle stampanti utilizzando tutte le proprietà, leggere ciascuna proprietà e aggiungere una nota al report finale che sarà presentato all'utente se tale proprietà è true. Il metodo ReportAvailabilityAtThisTime chiamato alla fine del codice viene illustrato di seguito.

        ' 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);
   };

Il metodo ReportAvailabilityAtThisTime è stato creato per i casi in cui è necessario determinare la disponibilità della coda all'ora corrente.

Il metodo non eseguirà alcuna operazione se le proprietà StartTimeOfDay e UntilTimeOfDay coincidono, perché in tal caso la stampante sarà sempre disponibile. Se non coincidono, il metodo ottiene l'ora corrente, che deve quindi essere convertita nel conteggio dei minuti complessivi trascorsi dalla mezzanotte, poiché le proprietà StartTimeOfDay e UntilTimeOfDay sono oggetti Int32 che rappresentano i minuti trascorsi dalla mezzanotte e non oggetti DateTime. Infine, il metodo verifica se l'ora corrente è compresa tra l'ora di inizio e l'ora di fine.

        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. ";
         }
      }
   };

Vedere anche

Riferimenti

StartTimeOfDay

UntilTimeOfDay

DateTime

PrintQueueStatus

Operatore & (Riferimenti per C#)

FlagsAttribute

GetPrintQueues

PrintServer

LocalPrintServer

EnumeratedPrintQueueTypes

PrintQueue

Concetti

Documenti in WPF

Cenni preliminari sulla stampa