Comment : observer à distance l'état d'imprimantes
Dans les moyennes et grandes entreprises, il peut arriver à tout moment que plusieurs imprimantes ne fonctionnent pas en raison d’un bourrage papier, d’un manque de papier ou d’un autre problème. L’ensemble complet de propriétés d’imprimante exposées dans les API de Microsoft .NET Framework permet d’effectuer une enquête rapide sur les états des imprimantes.
Exemple
Voici les principales étapes à suivre pour créer ce type d’utilitaire.
Répertoriez l’ensemble des serveurs d’impression.
Parcourez les serveurs en boucle pour interroger leurs files d’attente à l’impression.
À chaque étape de la boucle de serveur, parcourez en boucle toutes les files d’attente du serveur et lisez chaque propriété pouvant indiquer que la file d’attente ne fonctionne pas actuellement.
Le code ci-dessous est une série d’extraits de code. Pour plus de simplicité, cet exemple suppose qu’il existe une liste de serveurs d’impression délimitée par des caractères CRLF (retour chariot-saut de ligne). La variable fileOfPrintServers
est un StreamReader objet pour ce fichier. Étant donné que chaque nom de serveur se trouve sur sa propre ligne, tout appel d’obtient ReadLine le nom du serveur suivant et déplace le StreamReadercurseur vers le début de la ligne suivante.
Dans la boucle externe, le code crée un PrintServer objet pour le serveur d’impression le plus récent et spécifie que l’application doit disposer de droits d’administration sur le serveur.
Remarque
S’il existe un grand nombre de serveurs, vous pouvez améliorer les performances à l’aide des PrintServer(String, String[], PrintSystemDesiredAccess) constructeurs qui initialisent uniquement les propriétés dont vous aurez besoin.
L’exemple utilise GetPrintQueues ensuite pour créer une collection de toutes les files d’attente du serveur et commence à les parcourir en boucle. La boucle interne contient une structure en branches correspondant aux deux méthodes de vérification de l’état de l’imprimante :
Vous pouvez lire les indicateurs de la QueueStatus propriété de type PrintQueueStatus.
Vous pouvez lire chaque propriété pertinente telle que IsOutOfPaper, et IsPaperJammed.
Cet exemple illustre les deux méthodes, de sorte que l’utilisateur a été invité précédemment à indiquer quelle méthode utiliser et répondre avec « y » s’il voulait utiliser les indicateurs de la QueueStatus propriété. Voir ci-dessous pour obtenir des informations détaillées sur les deux méthodes.
Enfin, les résultats sont présentés à l’utilisateur.
// 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();
// 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
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()
Pour case activée’état de l’imprimante à l’aide des indicateurs de la QueueStatus propriété, vous case activée chaque indicateur approprié pour voir s’il est défini. La méthode standard pour voir si un bit est défini dans un ensemble d’indicateurs binaires consiste à effectuer une opération AND logique en utilisant comme opérandes l’ensemble d’indicateurs et l’indicateur lui-même. Étant donné que l’indicateur lui-même n’a qu’un seul bit de défini, l’opération AND logique ne peut pas trouver plus d’un même bit défini. Pour savoir si c’est bien le cas, il suffit de comparer le résultat de l’opération AND logique avec l’indicateur lui-même. Pour plus d’informations, consultez PrintQueueStatus, l’opérateur > (référence C#) et FlagsAttribute.
Pour chaque attribut dont le bit est défini, le code ajoute une note au rapport final qui sera présenté à l’utilisateur. (La méthode ReportAvailabilityAtThisTime qui est appelée à la fin du code est présentée ci-après.)
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);
};
// 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);
}
' 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
Pour vérifier l’état de l’imprimante à l’aide de chaque propriété, il vous suffit de lire chaque propriété et d’ajouter une note au rapport final qui sera présenté à l’utilisateur si la propriété est true
. (La méthode ReportAvailabilityAtThisTime qui est appelée à la fin du code est présentée ci-après.)
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);
};
// 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
' 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
La méthode ReportAvailabilityAtThisTime a été créée au cas où vous devriez déterminer si la file d’attente est disponible à l’heure actuelle.
La méthode ne fera rien si les propriétés et UntilTimeOfDay les StartTimeOfDay propriétés sont égales ; dans ce cas, l’imprimante est disponible à tout moment. Si elles sont différentes, la méthode obtient l’heure actuelle qui doit ensuite être convertie en minutes totales passées à minuit, car les StartTimeOfDay propriétés et UntilTimeOfDay les Int32propriétés représentent des minutes après minuit, et non DateTime des objets. Enfin, la méthode vérifie si l’heure actuelle se situe entre les heures de début et de fin.
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. ";
}
}
};
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 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
Voir aussi
.NET Desktop feedback