Comment : imprimer des fichiers XPS par programmation
Vous pouvez utiliser une surcharge de la méthode AddJob pour imprimer des fichiers XML Paper Specification (XPS) sans ouvrir de PrintDialog ni, en principe, aucune user interface (UI).
Vous pouvez également imprimer des fichiers XML Paper Specification (XPS) à l'aide des nombreuses méthodes Write et WriteAsync du XpsDocumentWriter. Pour plus d'informations à ce sujet, Printing an XPS Document.
Une autre façon d'imprimer du XML Paper Specification (XPS) est d'utiliser les méthodesPrintDocument ou PrintVisual du contrôle PrintDialog. Consultez Comment : appeler une boîte de dialogue Imprimer.
Exemple
Les étapes principales à l'utilisation de la méthode des trois paramètres AddJob(String, String, Boolean) sont les suivantes. L'exemple ci-dessous apporte des détails à ce sujet.
Déterminez si l'imprimante est une imprimante XPSDrv. (Consultez Vue d'ensemble de l'impression pour plus d'informations sur XPSDrv.)
Si l'imprimante n'est pas une imprimante XPSDrv, affectez STA (Single Thread Apartment) à l'état de cloisonnement du thread.
Instanciez un serveur d'impression et un objet de la file d'attente à l'impression.
Appelez la méthode, en spécifiant le nom du travail, le fichier à imprimer et un indicateur Boolean qui signale si l'imprimante est une imprimante XPSDrv ou pas.
L'exemple suivant montre comment imprimer par lots tous les fichiers XPS dans un répertoire. Bien que l'application invite l'utilisateur à spécifier le répertoire, la méthode des trois paramètres AddJob(String, String, Boolean) ne requiert pas d'user interface (UI). Elle peut être utilisée dans un chemin d'accès au code dans lequel vous avez un nom de fichier XPS et un chemin d'accès que vous pouvez passer à celui-ci.
La surcharge des trois paramètres AddJob(String, String, Boolean) de AddJob doit s'exécuter dans un thread unique cloisonné (STA) toutes les fois que le paramètre Boolean est false, ce qui doit être le cas lorsqu'une imprimante qui n'est pas une imprimante XPSDrv est utilisée. Toutefois, l'état de cloisonnement par défaut pour Microsoft .NET est plusieurs threads. Cet état par défaut doit être inversé puisque l'exemple illustre une imprimante qui n'est pas une imprimante XPSDrv.
Il existe deux manières de modifier l'état par défaut. L'un des moyens consiste simplement à ajouter STAThreadAttribute (autrement dit, "[System.STAThreadAttribute()]") juste au-dessus de la première ligne de la méthode Main de l'application (habituellement "static void Main(string[] args)"). Toutefois, de nombreuses applications exigent de la méthode Main qu'elle ait un état de cloisonnement multithread, il existe donc une deuxième méthode : placez l'appel à AddJob(String, String, Boolean) dans un thread séparé dont l'état de cloisonnement a la valeur STA avec SetApartmentState. L'exemple suivant utilise cette deuxième technique.
En conséquence, l'exemple commence en instanciant un objet Thread et lui passant une méthode PrintXPS comme paramètre ThreadStart. (La méthode PrintXPS est définie ultérieurement dans l'exemple.) Ensuite, le thread est configuré en thread unique cloisonné (STA). Le seul code restant de la méthode Main démarre le nouveau thread.
L'essentiel de l'exemple se trouve dans la méthode static BatchXPSPrinter.PrintXPS. Après avoir créé un serveur d'impression et une file d'attente, la méthode invite l'utilisateur à entrer un répertoire contenant des fichiers XPS. Après avoir validé l'existence du répertoire et la présence de fichiers *.xps dans celui-ci, la méthode ajoute chacun de ces fichiers à la file d'attente à l'impression. L'exemple supposant que l'imprimante n'est pas une imprimante XPSDrv, nous passons donc false au dernier paramètre de la méthode AddJob(String, String, Boolean). Pour cette raison, la méthode validera le balisage XPS dans le fichier avant d'essayer de le convertir en langage de description de page de l'imprimante. Si la validation échoue, une exception est levée. L'exemple de code interceptera l'exception, notifiera l'utilisateur à son propos, puis passera au traitement du fichier XPS suivant.
Friend Class Program
<System.MTAThreadAttribute()>
Shared Sub Main(ByVal args() As String) ' Added for clarity, but this line is redundant because MTA is the default.
' Create the secondary thread and pass the printing method for
' the constructor's ThreadStart delegate parameter. The BatchXPSPrinter
' class is defined below.
Dim printingThread As New Thread(AddressOf BatchXPSPrinter.PrintXPS)
' Set the thread that will use PrintQueue.AddJob to single threading.
printingThread.SetApartmentState(ApartmentState.STA)
' Start the printing thread. The method passed to the Thread
' constructor will execute.
printingThread.Start()
End Sub 'end Main
End Class 'end Program class
Public Class BatchXPSPrinter
Public Shared Sub PrintXPS()
' Create print server and print queue.
Dim localPrintServer As New LocalPrintServer()
Dim defaultPrintQueue As PrintQueue = LocalPrintServer.GetDefaultPrintQueue()
' Prompt user to identify the directory, and then create the directory object.
Console.Write("Enter the directory containing the XPS files: ")
Dim directoryPath As String = Console.ReadLine()
Dim dir As New DirectoryInfo(directoryPath)
' If the user mistyped, end the thread and return to the Main thread.
If Not dir.Exists Then
Console.WriteLine("There is no such directory.")
Else
' If there are no XPS files in the directory, end the thread
' and return to the Main thread.
If dir.GetFiles("*.xps").Length = 0 Then
Console.WriteLine("There are no XPS files in the directory.")
Else
Console.WriteLine(vbLf & "Jobs will now be added to the print queue.")
Console.WriteLine("If the queue is not paused and the printer is working, jobs will begin printing.")
' Batch process all XPS files in the directory.
For Each f As FileInfo In dir.GetFiles("*.xps")
Dim nextFile As String = directoryPath & "\" & f.Name
Console.WriteLine("Adding {0} to queue.", nextFile)
Try
' Print the Xps file while providing XPS validation and progress notifications.
Dim xpsPrintJob As PrintSystemJobInfo = defaultPrintQueue.AddJob(f.Name, nextFile, False)
Catch e As PrintJobException
Console.WriteLine(vbLf & vbTab & "{0} could not be added to the print queue.", f.Name)
If e.InnerException.Message = "File contains corrupted data." Then
Console.WriteLine(vbTab & "It is not a valid XPS file. Use the isXPS Conformance Tool to debug it.")
End If
Console.WriteLine(vbTab & "Continuing with next XPS file." & vbLf)
End Try
Next f ' end for each XPS file
End If 'end if there are no XPS files in the directory
End If 'end if the directory does not exist
Console.WriteLine("Press Enter to end program.")
Console.ReadLine()
End Sub ' end PrintXPS method
End Class ' end BatchXPSPrinter class
class Program
{
[System.MTAThreadAttribute()] // Added for clarity, but this line is redundant because MTA is the default.
static void Main(string[] args)
{
// Create the secondary thread and pass the printing method for
// the constructor's ThreadStart delegate parameter. The BatchXPSPrinter
// class is defined below.
Thread printingThread = new Thread(BatchXPSPrinter.PrintXPS);
// Set the thread that will use PrintQueue.AddJob to single threading.
printingThread.SetApartmentState(ApartmentState.STA);
// Start the printing thread. The method passed to the Thread
// constructor will execute.
printingThread.Start();
}//end Main
}//end Program class
public class BatchXPSPrinter
{
public static void PrintXPS()
{
// Create print server and print queue.
LocalPrintServer localPrintServer = new LocalPrintServer();
PrintQueue defaultPrintQueue = LocalPrintServer.GetDefaultPrintQueue();
// Prompt user to identify the directory, and then create the directory object.
Console.Write("Enter the directory containing the XPS files: ");
String directoryPath = Console.ReadLine();
DirectoryInfo dir = new DirectoryInfo(directoryPath);
// If the user mistyped, end the thread and return to the Main thread.
if (!dir.Exists)
{
Console.WriteLine("There is no such directory.");
}
else
{
// If there are no XPS files in the directory, end the thread
// and return to the Main thread.
if (dir.GetFiles("*.xps").Length == 0)
{
Console.WriteLine("There are no XPS files in the directory.");
}
else
{
Console.WriteLine("\nJobs will now be added to the print queue.");
Console.WriteLine("If the queue is not paused and the printer is working, jobs will begin printing.");
// Batch process all XPS files in the directory.
foreach (FileInfo f in dir.GetFiles("*.xps"))
{
String nextFile = directoryPath + "\\" + f.Name;
Console.WriteLine("Adding {0} to queue.", nextFile);
try
{
// Print the Xps file while providing XPS validation and progress notifications.
PrintSystemJobInfo xpsPrintJob = defaultPrintQueue.AddJob(f.Name, nextFile, false);
}
catch (PrintJobException e)
{
Console.WriteLine("\n\t{0} could not be added to the print queue.", f.Name);
if (e.InnerException.Message == "File contains corrupted data.")
{
Console.WriteLine("\tIt is not a valid XPS file. Use the isXPS Conformance Tool to debug it.");
}
Console.WriteLine("\tContinuing with next XPS file.\n");
}
}// end for each XPS file
}//end if there are no XPS files in the directory
}//end if the directory does not exist
Console.WriteLine("Press Enter to end program.");
Console.ReadLine();
}// end PrintXPS method
}// end BatchXPSPrinter class
Si vous utilisez une imprimante XPSDrv, vous pouvez alors affecter la valeur true au dernier paramètre. Dans ce cas, puisque XPS est le langage de description de page de l'imprimante, la méthode enverra le fichier à l'imprimante sans le valider ou le convertir dans un autre langage. Si vous n'êtes pas certain, au moment du design de savoir si l'application utilisera une imprimante XPSDrv ou pas, vous pouvez modifier l'application pour qu'elle lise la propriété IsXpsDevice et crée une branche en fonction de ce qu'elle trouve.
Puisque initialement peu d'imprimantes XPSDrv seront disponibles immédiatement après la version finale de Windows Vista et de Microsoft .NET Framework, vous pouvez être amené à déguiser une imprimante qui n'est pas une imprimante XPSDrv en imprimante XPSDrv. Pour cela, ajoutez Pipelineconfig.xml à la liste des fichiers dans la clé de Registre suivante de l'ordinateur qui exécute votre application :
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Environments\Windows NT x86\Drivers\Version-3\<PseudoXPSPrinter>\DependentFiles
où <PseudoXPSPrinter> est une file d'attente à l'impression quelconque. Puis l'ordinateur doit être redémarré.
Ce déguisement vous permettra de passer true comme dernier paramètre de AddJob(String, String, Boolean) sans provoquer une exception, mais puisque <PseudoXPSPrinter > n'est pas vraiment une imprimante XPSDrv, des informations superflues seront imprimées.
Remarque Par simplicité, l'exemple ci-dessus utilise la présence d'une extension *.xps pour tester qu'un fichier est XPS. Toutefois, des fichiers XPS peuvent avoir une extension différente. L' isXPS.exe (isXPS Conformance Tool) est un moyen de tester la validité XPS d'un fichier.
Voir aussi
Tâches
Référence
Concepts
Threading managé et non managé
isXPS.exe (isXPS Conformance Tool)
Vue d'ensemble de l'impression