Comment : diagnostiquer un travail d'impression problématique
Les administrateurs de réseaux reçoivent souvent des plaintes des utilisateurs à propos des travaux d'impression qui échouent ou sont trop lents. Les très nombreuses propriétés de travail d'impression proposées dans les APIs de Microsoft .NET Framework permettent d'effectuer rapidement un diagnostic à distance des travaux d'impression.
Exemple
Les étapes principales pour créer ce type d'utilitaire sont les suivantes :
Identifier le travail d'impression dont se plaint l'utilisateur. Souvent, les indications fournies par les utilisateurs ne sont pas très précises. Ils ne connaissant pas nécessairement les noms de leurs serveurs d'impression ou imprimantes. Ils peuvent décrire l'emplacement de l'imprimante avec une terminologie différente de celle utilisée dans la définition de la propriété Location. C'est pourquoi il est utile de générer une liste des travaux actuellement soumis par l'utilisateur. Si plusieurs travaux sont en attente d'impression, la communication entre l'utilisateur et l'administrateur du système d'impression peut permettre de localiser le travail problématique. Les sous-étapes sont les suivantes :
Obtenir une liste de tous les serveurs d'impression.
Parcourir les serveurs pour interroger leurs files d'attente à l'impression.
À chaque exploration du serveur, parcourir toutes les files d'attente de ce serveur pour interroger leurs travaux
À chaque exploration de la file d'attente, parcourir ses travaux et rassembler des indications sur ceux soumis par l'utilisateur plaignant.
Une fois le travail d'impression problématique identifié, examiner les propriétés appropriées pour tenter de cerner le problème. Par exemple, le travail est-il en état d'erreur ou l'imprimante qui dessert la file d'attente a-t-elle été éteinte avant l'impression du travail ?
Vous trouverez ci-dessous une série d'exemples de code. Le premier exemple de code illustre le parcours des files d'attente à l'impression. (Étape 1c ci-dessus.) La variable myPrintQueues est l'objet PrintQueueCollection pour le serveur d'impression actif.
L'exemple de code commence par actualiser l'objet de file d'attente à l'impression en utilisant PrintQueue.Refresh. Cela garantit que les propriétés de l'objet représentent exactement l'état de l'imprimante physique correspondante. L'application obtient ensuite l'ensemble des travaux d'impression actuellement placés dans la file d'attente à l'impression en utilisant GetPrintJobInfoCollection.
Ensuite, l'application parcourt la collection PrintSystemJobInfo et compare chaque propriété Submitter à l'alias de l'utilisateur plaignant. Si ces éléments concordent, l'application ajoute les informations d'identification du travail à la chaîne qui sera présentée. (Les variables userName et jobList sont initialisées précédemment dans l'application.)
For Each pq As PrintQueue In myPrintQueues
pq.Refresh()
Dim jobs As PrintJobInfoCollection = pq.GetPrintJobInfoCollection()
For Each job As PrintSystemJobInfo In jobs
' Since the user may not be able to articulate which job is problematic,
' present information about each job the user has submitted.
If job.Submitter = userName Then
atLeastOne = True
jobList = jobList & vbLf & "Server:" & line
jobList = jobList & vbLf & vbTab & "Queue:" & pq.Name
jobList = jobList & vbLf & vbTab & "Location:" & pq.Location
jobList = jobList & vbLf & vbTab & vbTab & "Job: " & job.JobName & " ID: " & job.JobIdentifier
End If
Next job ' end for each print job
Next pq ' end for each print queue
foreach (PrintQueue pq in myPrintQueues)
{
pq.Refresh();
PrintJobInfoCollection jobs = pq.GetPrintJobInfoCollection();
foreach (PrintSystemJobInfo job in jobs)
{
// Since the user may not be able to articulate which job is problematic,
// present information about each job the user has submitted.
if (job.Submitter == userName)
{
atLeastOne = true;
jobList = jobList + "\nServer:" + line;
jobList = jobList + "\n\tQueue:" + pq.Name;
jobList = jobList + "\n\tLocation:" + pq.Location;
jobList = jobList + "\n\t\tJob: " + job.JobName + " ID: " + job.JobIdentifier;
}
}// end for each print job
}// end for each print queue
for each (PrintQueue^ pq in myPrintQueues)
{
pq->Refresh();
PrintJobInfoCollection^ jobs = pq->GetPrintJobInfoCollection();
for each (PrintSystemJobInfo^ job in jobs)
{
// Since the user may not be able to articulate which job is problematic,
// present information about each job the user has submitted.
if (job->Submitter == userName)
{
atLeastOne = true;
jobList = jobList + "\nServer:" + line;
jobList = jobList + "\n\tQueue:" + pq->Name;
jobList = jobList + "\n\tLocation:" + pq->Location;
jobList = jobList + "\n\t\tJob: " + job->JobName + " ID: " + job->JobIdentifier;
}
}
}
L'exemple de code suivant reprend l'application de l'étape 2. (Voir ci-dessus.) Le travail problématique a été repéré et l'application demande les informations d'identification. À partir de ces informations, elle crée les objets PrintServer, PrintQueue et PrintSystemJobInfo.
À ce stade, l'application contient une structure de branche qui correspond aux deux façons de vérifier l'état d'un travail d'impression :
Vous pouvez lire les indicateurs de la propriété JobStatus qui est du type PrintJobStatus.
Vous pouvez lire chaque propriété appropriée telle que IsBlocked et IsInError.
Cet exemple illustrant les deux méthodes, l'utilisateur a été auparavant invité à choisir celle à utiliser et a répondu par l'affirmative s'il souhaitait opter pour les indicateurs de la propriété JobStatus. Voir ci-dessous pour des informations détaillées sur les deux méthodes. Enfin, l'application utilise une méthode appelée ReportQueueAndJobAvailability pour préciser si le travail peut être imprimé à ce moment de la journée. Cette méthode est décrite dans Comment : déterminer si un travail d'impression peut être imprimé à cette heure de la journée.
' When the problematic print job has been identified, enter information about it.
Console.Write(vbLf & "Enter the print server hosting the job (including leading slashes \\): " & vbLf & "(press Return for the current computer \\{0}): ", Environment.MachineName)
Dim pServer As String = Console.ReadLine()
If pServer = "" Then
pServer = "\\" & Environment.MachineName
End If
Console.Write(vbLf & "Enter the print queue hosting the job: ")
Dim pQueue As String = Console.ReadLine()
Console.Write(vbLf & "Enter the job ID: ")
Dim jobID As Int16 = Convert.ToInt16(Console.ReadLine())
' Create objects to represent the server, queue, and print job.
Dim hostingServer As New PrintServer(pServer, PrintSystemDesiredAccess.AdministrateServer)
Dim hostingQueue As New PrintQueue(hostingServer, pQueue, PrintSystemDesiredAccess.AdministratePrinter)
Dim theJob As PrintSystemJobInfo = hostingQueue.GetJob(jobID)
If useAttributesResponse = "Y" Then
TroubleSpotter.SpotTroubleUsingJobAttributes(theJob)
' TroubleSpotter class is defined in the complete example.
Else
TroubleSpotter.SpotTroubleUsingProperties(theJob)
End If
TroubleSpotter.ReportQueueAndJobAvailability(theJob)
// When the problematic print job has been identified, enter information about it.
Console.Write("\nEnter the print server hosting the job (including leading slashes \\\\): " +
"\n(press Return for the current computer \\\\{0}): ", Environment.MachineName);
String pServer = Console.ReadLine();
if (pServer == "")
{
pServer = "\\\\" +Environment.MachineName;
}
Console.Write("\nEnter the print queue hosting the job: ");
String pQueue = Console.ReadLine();
Console.Write("\nEnter the job ID: ");
Int16 jobID = Convert.ToInt16(Console.ReadLine());
// Create objects to represent the server, queue, and print job.
PrintServer hostingServer = new PrintServer(pServer, PrintSystemDesiredAccess.AdministrateServer);
PrintQueue hostingQueue = new PrintQueue(hostingServer, pQueue, PrintSystemDesiredAccess.AdministratePrinter);
PrintSystemJobInfo theJob = hostingQueue.GetJob(jobID);
if (useAttributesResponse == "Y")
{
TroubleSpotter.SpotTroubleUsingJobAttributes(theJob);
// TroubleSpotter class is defined in the complete example.
}
else
{
TroubleSpotter.SpotTroubleUsingProperties(theJob);
}
TroubleSpotter.ReportQueueAndJobAvailability(theJob);
// When the problematic print job has been identified, enter information about it.
Console::Write("\nEnter the print server hosting the job (including leading slashes \\\\): " + "\n(press Return for the current computer \\\\{0}): ", Environment::MachineName);
String^ pServer = Console::ReadLine();
if (pServer == "")
{
pServer = "\\\\" + Environment::MachineName;
}
Console::Write("\nEnter the print queue hosting the job: ");
String^ pQueue = Console::ReadLine();
Console::Write("\nEnter the job ID: ");
Int16 jobID = Convert::ToInt16(Console::ReadLine());
// Create objects to represent the server, queue, and print job.
PrintServer^ hostingServer = gcnew PrintServer(pServer, PrintSystemDesiredAccess::AdministrateServer);
PrintQueue^ hostingQueue = gcnew PrintQueue(hostingServer, pQueue, PrintSystemDesiredAccess::AdministratePrinter);
PrintSystemJobInfo^ theJob = hostingQueue->GetJob(jobID);
if (useAttributesResponse == "Y")
{
TroubleSpotter::SpotTroubleUsingJobAttributes(theJob);
// TroubleSpotter class is defined in the complete example.
} else
{
TroubleSpotter::SpotTroubleUsingProperties(theJob);
}
TroubleSpotter::ReportQueueAndJobAvailability(theJob);
Pour vérifier l'état du travail d'impression au moyen des indicateurs de la propriété JobStatus, vous contrôlez si chaque indicateur correspondant est défini. La procédure standard pour vérifier si l'un des bits d'un ensemble de bits indicateurs est défini consiste à effectuer une opération AND logique en spécifiant l'ensemble d'indicateurs comme premier opérande et l'indicateur lui-même comme deuxième opérande. Comme l'indicateur lui-même n'a qu'un seul bit défini, le résultat du AND logique est que, au plus, ce même bit est défini. Pour déterminer si c'est le cas ou non, il suffit de comparer le résultat du AND logique à l'indicateur lui-même. Pour plus d'informations, consultez PrintJobStatus, l'&, opérateur (référence C#) et FlagsAttribute.
Pour chaque attribut dont le bit est défini, le code affiche cette information sur l'écran de la console et propose parfois une réponse possible. (La méthode HandlePausedJob qui est appelée si le travail ou la file d'attente sont suspendus est abordée ci-dessous.)
' Check for possible trouble states of a print job using the flags of the JobStatus property
Friend Shared Sub SpotTroubleUsingJobAttributes(ByVal theJob As PrintSystemJobInfo)
If (theJob.JobStatus And PrintJobStatus.Blocked) = PrintJobStatus.Blocked Then
Console.WriteLine("The job is blocked.")
End If
If ((theJob.JobStatus And PrintJobStatus.Completed) = PrintJobStatus.Completed) OrElse ((theJob.JobStatus And PrintJobStatus.Printed) = PrintJobStatus.Printed) Then
Console.WriteLine("The job has finished. Have user recheck all output bins and be sure the correct printer is being checked.")
End If
If ((theJob.JobStatus And PrintJobStatus.Deleted) = PrintJobStatus.Deleted) OrElse ((theJob.JobStatus And PrintJobStatus.Deleting) = PrintJobStatus.Deleting) Then
Console.WriteLine("The user or someone with administration rights to the queue has deleted the job. It must be resubmitted.")
End If
If (theJob.JobStatus And PrintJobStatus.Error) = PrintJobStatus.Error Then
Console.WriteLine("The job has errored.")
End If
If (theJob.JobStatus And PrintJobStatus.Offline) = PrintJobStatus.Offline Then
Console.WriteLine("The printer is offline. Have user put it online with printer front panel.")
End If
If (theJob.JobStatus And PrintJobStatus.PaperOut) = PrintJobStatus.PaperOut Then
Console.WriteLine("The printer is out of paper of the size required by the job. Have user add paper.")
End If
If ((theJob.JobStatus And PrintJobStatus.Paused) = PrintJobStatus.Paused) OrElse ((theJob.HostingPrintQueue.QueueStatus And PrintQueueStatus.Paused) = PrintQueueStatus.Paused) Then
HandlePausedJob(theJob)
'HandlePausedJob is defined in the complete example.
End If
If (theJob.JobStatus And PrintJobStatus.Printing) = PrintJobStatus.Printing Then
Console.WriteLine("The job is printing now.")
End If
If (theJob.JobStatus And PrintJobStatus.Spooling) = PrintJobStatus.Spooling Then
Console.WriteLine("The job is spooling now.")
End If
If (theJob.JobStatus And PrintJobStatus.UserIntervention) = PrintJobStatus.UserIntervention Then
Console.WriteLine("The printer needs human intervention.")
End If
End Sub 'end SpotTroubleUsingJobAttributes
// Check for possible trouble states of a print job using the flags of the JobStatus property
internal static void SpotTroubleUsingJobAttributes(PrintSystemJobInfo theJob)
{
if ((theJob.JobStatus & PrintJobStatus.Blocked) == PrintJobStatus.Blocked)
{
Console.WriteLine("The job is blocked.");
}
if (((theJob.JobStatus & PrintJobStatus.Completed) == PrintJobStatus.Completed)
||
((theJob.JobStatus & PrintJobStatus.Printed) == PrintJobStatus.Printed))
{
Console.WriteLine("The job has finished. Have user recheck all output bins and be sure the correct printer is being checked.");
}
if (((theJob.JobStatus & PrintJobStatus.Deleted) == PrintJobStatus.Deleted)
||
((theJob.JobStatus & PrintJobStatus.Deleting) == PrintJobStatus.Deleting))
{
Console.WriteLine("The user or someone with administration rights to the queue has deleted the job. It must be resubmitted.");
}
if ((theJob.JobStatus & PrintJobStatus.Error) == PrintJobStatus.Error)
{
Console.WriteLine("The job has errored.");
}
if ((theJob.JobStatus & PrintJobStatus.Offline) == PrintJobStatus.Offline)
{
Console.WriteLine("The printer is offline. Have user put it online with printer front panel.");
}
if ((theJob.JobStatus & PrintJobStatus.PaperOut) == PrintJobStatus.PaperOut)
{
Console.WriteLine("The printer is out of paper of the size required by the job. Have user add paper.");
}
if (((theJob.JobStatus & PrintJobStatus.Paused) == PrintJobStatus.Paused)
||
((theJob.HostingPrintQueue.QueueStatus & PrintQueueStatus.Paused) == PrintQueueStatus.Paused))
{
HandlePausedJob(theJob);
//HandlePausedJob is defined in the complete example.
}
if ((theJob.JobStatus & PrintJobStatus.Printing) == PrintJobStatus.Printing)
{
Console.WriteLine("The job is printing now.");
}
if ((theJob.JobStatus & PrintJobStatus.Spooling) == PrintJobStatus.Spooling)
{
Console.WriteLine("The job is spooling now.");
}
if ((theJob.JobStatus & PrintJobStatus.UserIntervention) == PrintJobStatus.UserIntervention)
{
Console.WriteLine("The printer needs human intervention.");
}
}//end SpotTroubleUsingJobAttributes
// Check for possible trouble states of a print job using the flags of the JobStatus property
static void SpotTroubleUsingJobAttributes (PrintSystemJobInfo^ theJob)
{
if ((theJob->JobStatus & PrintJobStatus::Blocked) == PrintJobStatus::Blocked)
{
Console::WriteLine("The job is blocked.");
}
if (((theJob->JobStatus & PrintJobStatus::Completed) == PrintJobStatus::Completed)
||
((theJob->JobStatus & PrintJobStatus::Printed) == PrintJobStatus::Printed))
{
Console::WriteLine("The job has finished. Have user recheck all output bins and be sure the correct printer is being checked.");
}
if (((theJob->JobStatus & PrintJobStatus::Deleted) == PrintJobStatus::Deleted)
||
((theJob->JobStatus & PrintJobStatus::Deleting) == PrintJobStatus::Deleting))
{
Console::WriteLine("The user or someone with administration rights to the queue has deleted the job. It must be resubmitted.");
}
if ((theJob->JobStatus & PrintJobStatus::Error) == PrintJobStatus::Error)
{
Console::WriteLine("The job has errored.");
}
if ((theJob->JobStatus & PrintJobStatus::Offline) == PrintJobStatus::Offline)
{
Console::WriteLine("The printer is offline. Have user put it online with printer front panel.");
}
if ((theJob->JobStatus & PrintJobStatus::PaperOut) == PrintJobStatus::PaperOut)
{
Console::WriteLine("The printer is out of paper of the size required by the job. Have user add paper.");
}
if (((theJob->JobStatus & PrintJobStatus::Paused) == PrintJobStatus::Paused)
||
((theJob->HostingPrintQueue->QueueStatus & PrintQueueStatus::Paused) == PrintQueueStatus::Paused))
{
HandlePausedJob(theJob);
//HandlePausedJob is defined in the complete example.
}
if ((theJob->JobStatus & PrintJobStatus::Printing) == PrintJobStatus::Printing)
{
Console::WriteLine("The job is printing now.");
}
if ((theJob->JobStatus & PrintJobStatus::Spooling) == PrintJobStatus::Spooling)
{
Console::WriteLine("The job is spooling now.");
}
if ((theJob->JobStatus & PrintJobStatus::UserIntervention) == PrintJobStatus::UserIntervention)
{
Console::WriteLine("The printer needs human intervention.");
}
};
Pour vérifier l'état du travail d'impression à l'aide de propriétés individuelles, il vous suffit de lire chaque propriété et, si elle a la valeur true, d'afficher cette information sur l'écran de la console en proposant éventuellement une réponse possible. (La méthode HandlePausedJob qui est appelée si le travail ou la file d'attente sont suspendus est abordée ci-dessous.)
' Check for possible trouble states of a print job using its properties
Friend Shared Sub SpotTroubleUsingProperties(ByVal theJob As PrintSystemJobInfo)
If theJob.IsBlocked Then
Console.WriteLine("The job is blocked.")
End If
If theJob.IsCompleted OrElse theJob.IsPrinted Then
Console.WriteLine("The job has finished. Have user recheck all output bins and be sure the correct printer is being checked.")
End If
If theJob.IsDeleted OrElse theJob.IsDeleting Then
Console.WriteLine("The user or someone with administration rights to the queue has deleted the job. It must be resubmitted.")
End If
If theJob.IsInError Then
Console.WriteLine("The job has errored.")
End If
If theJob.IsOffline Then
Console.WriteLine("The printer is offline. Have user put it online with printer front panel.")
End If
If theJob.IsPaperOut Then
Console.WriteLine("The printer is out of paper of the size required by the job. Have user add paper.")
End If
If theJob.IsPaused OrElse theJob.HostingPrintQueue.IsPaused Then
HandlePausedJob(theJob)
'HandlePausedJob is defined in the complete example.
End If
If theJob.IsPrinting Then
Console.WriteLine("The job is printing now.")
End If
If theJob.IsSpooling Then
Console.WriteLine("The job is spooling now.")
End If
If theJob.IsUserInterventionRequired Then
Console.WriteLine("The printer needs human intervention.")
End If
End Sub 'end SpotTroubleUsingProperties
// Check for possible trouble states of a print job using its properties
internal static void SpotTroubleUsingProperties(PrintSystemJobInfo theJob)
{
if (theJob.IsBlocked)
{
Console.WriteLine("The job is blocked.");
}
if (theJob.IsCompleted || theJob.IsPrinted)
{
Console.WriteLine("The job has finished. Have user recheck all output bins and be sure the correct printer is being checked.");
}
if (theJob.IsDeleted || theJob.IsDeleting)
{
Console.WriteLine("The user or someone with administration rights to the queue has deleted the job. It must be resubmitted.");
}
if (theJob.IsInError)
{
Console.WriteLine("The job has errored.");
}
if (theJob.IsOffline)
{
Console.WriteLine("The printer is offline. Have user put it online with printer front panel.");
}
if (theJob.IsPaperOut)
{
Console.WriteLine("The printer is out of paper of the size required by the job. Have user add paper.");
}
if (theJob.IsPaused || theJob.HostingPrintQueue.IsPaused)
{
HandlePausedJob(theJob);
//HandlePausedJob is defined in the complete example.
}
if (theJob.IsPrinting)
{
Console.WriteLine("The job is printing now.");
}
if (theJob.IsSpooling)
{
Console.WriteLine("The job is spooling now.");
}
if (theJob.IsUserInterventionRequired)
{
Console.WriteLine("The printer needs human intervention.");
}
}//end SpotTroubleUsingProperties
// Check for possible trouble states of a print job using its properties
static void SpotTroubleUsingProperties (PrintSystemJobInfo^ theJob)
{
if (theJob->IsBlocked)
{
Console::WriteLine("The job is blocked.");
}
if (theJob->IsCompleted || theJob->IsPrinted)
{
Console::WriteLine("The job has finished. Have user recheck all output bins and be sure the correct printer is being checked.");
}
if (theJob->IsDeleted || theJob->IsDeleting)
{
Console::WriteLine("The user or someone with administration rights to the queue has deleted the job. It must be resubmitted.");
}
if (theJob->IsInError)
{
Console::WriteLine("The job has errored.");
}
if (theJob->IsOffline)
{
Console::WriteLine("The printer is offline. Have user put it online with printer front panel.");
}
if (theJob->IsPaperOut)
{
Console::WriteLine("The printer is out of paper of the size required by the job. Have user add paper.");
}
if (theJob->IsPaused || theJob->HostingPrintQueue->IsPaused)
{
HandlePausedJob(theJob);
//HandlePausedJob is defined in the complete example.
}
if (theJob->IsPrinting)
{
Console::WriteLine("The job is printing now.");
}
if (theJob->IsSpooling)
{
Console::WriteLine("The job is spooling now.");
}
if (theJob->IsUserInterventionRequired)
{
Console::WriteLine("The printer needs human intervention.");
}
};
La méthode HandlePausedJob permet à l'utilisateur d'une application de reprendre à distance des travaux suspendus. Comme la file d'attente à l'impression a peut-être été suspendue pour de bonnes raisons, la méthode demande à l'utilisateur de confirmer sa décision de reprise. En cas de réponse affirmative, la méthode PrintQueue.Resume est appelée.
L'utilisateur est ensuite invité à confirmer si le travail lui-même doit reprendre, juste au cas où il ait été suspendu indépendamment de la file d'attente à l'impression. Comparez PrintQueue.IsPaused et PrintSystemJobInfo.IsPaused. Si l'utilisateur répond par l'affirmative, PrintSystemJobInfo.Resume est appelée, sinon c'est Cancel.
Friend Shared Sub HandlePausedJob(ByVal theJob As PrintSystemJobInfo)
' If there's no good reason for the queue to be paused, resume it and
' give user choice to resume or cancel the job.
Console.WriteLine("The user or someone with administrative rights to the queue" & vbLf & "has paused the job or queue." & vbLf & "Resume the queue? (Has no effect if queue is not paused.)" & vbLf & "Enter ""Y"" to resume, otherwise press return: ")
Dim [resume] As String = Console.ReadLine()
If [resume] = "Y" Then
theJob.HostingPrintQueue.Resume()
' It is possible the job is also paused. Find out how the user wants to handle that.
Console.WriteLine("Does user want to resume print job or cancel it?" & vbLf & "Enter ""Y"" to resume (any other key cancels the print job): ")
Dim userDecision As String = Console.ReadLine()
If userDecision = "Y" Then
theJob.Resume()
Else
theJob.Cancel()
End If
End If 'end if the queue should be resumed
End Sub 'end HandlePausedJob
internal static void HandlePausedJob(PrintSystemJobInfo theJob)
{
// If there's no good reason for the queue to be paused, resume it and
// give user choice to resume or cancel the job.
Console.WriteLine("The user or someone with administrative rights to the queue" +
"\nhas paused the job or queue." +
"\nResume the queue? (Has no effect if queue is not paused.)" +
"\nEnter \"Y\" to resume, otherwise press return: ");
String resume = Console.ReadLine();
if (resume == "Y")
{
theJob.HostingPrintQueue.Resume();
// It is possible the job is also paused. Find out how the user wants to handle that.
Console.WriteLine("Does user want to resume print job or cancel it?" +
"\nEnter \"Y\" to resume (any other key cancels the print job): ");
String userDecision = Console.ReadLine();
if (userDecision == "Y")
{
theJob.Resume();
}
else
{
theJob.Cancel();
}
}//end if the queue should be resumed
}//end HandlePausedJob
static void HandlePausedJob (PrintSystemJobInfo^ theJob)
{
// If there's no good reason for the queue to be paused, resume it and
// give user choice to resume or cancel the job.
Console::WriteLine("The user or someone with administrative rights to the queue" + "\nhas paused the job or queue." + "\nResume the queue? (Has no effect if queue is not paused.)" + "\nEnter \"Y\" to resume, otherwise press return: ");
String^ resume = Console::ReadLine();
if (resume == "Y")
{
theJob->HostingPrintQueue->Resume();
// It is possible the job is also paused. Find out how the user wants to handle that.
Console::WriteLine("Does user want to resume print job or cancel it?" + "\nEnter \"Y\" to resume (any other key cancels the print job): ");
String^ userDecision = Console::ReadLine();
if (userDecision == "Y")
{
theJob->Resume();
} else
{
theJob->Cancel();
}
}
};