Procedura: stampa di file XPS a livello di codice
È possibile utilizzare un overload del AddJob metodo per stampare file XPS (XML Paper Specification) senza aprire PrintDialog o, in linea di principio, qualsiasi interfaccia utente .
È anche possibile stampare i file XPS usando i numerosi XpsDocumentWriter.Write metodi e XpsDocumentWriter.WriteAsync . Per altre informazioni, vedere Stampa di un documento XPS.
Un altro modo per stampare XPS consiste nell'usare i PrintDialog.PrintDocument metodi o PrintDialog.PrintVisual . Vedere Richiamare una finestra di dialogo Stampa.
Esempio
I passaggi principali per l'uso del metodo a tre parametri AddJob(String, String, Boolean) sono i seguenti. L'esempio riportato di seguito offre delle informazioni dettagliate.
Determinare se la stampante è una stampante XPSDrv. Per altre informazioni su XPSDrv, vedere Panoramica della stampa.
Se la stampante non è una stampante XPSDrv, impostare l'apartment del thread a thread singolo.
Creare un'istanza di un server di stampa e un oggetto coda di stampa.
Chiamare il metodo , specificando un nome di processo, il file da stampare e un Boolean flag che indica se la stampante è o meno una stampante XPSDrv.
L'esempio seguente illustra come eseguire il batch per stampare in batch tutti i file XPS in una directory. Anche se l'applicazione richiede all'utente di specificare la directory, il metodo a tre parametri AddJob(String, String, Boolean) non richiede un'interfaccia utente. Può essere usato in qualsiasi percorso di codice in cui si dispone di un nome di file XPS e un percorso che è possibile passare a esso.
L'overload a tre parametri AddJob(String, String, Boolean) di AddJob deve essere eseguito in un apartment a thread singolo ogni volta che il Boolean parametro è false
, che deve essere quando viene usata una stampante non XPSDrv. Tuttavia, lo stato apartment predefinito per .NET è costituito da più thread. Questa impostazione predefinita deve essere annullata poiché nell'esempio si presuppone una stampante non XPSDrv.
Ci sono due modi per modificare il valore predefinito. Un modo consiste semplicemente nell'aggiungere ( STAThreadAttribute ovvero "[System.STAThreadAttribute()]
") appena sopra la prima riga del metodo dell'applicazione Main
(in genere "static void Main(string[] args)
"). Tuttavia, molte applicazioni richiedono che il Main
metodo abbia uno stato apartment a thread multipli, quindi esiste un secondo metodo: inserire la chiamata a AddJob(String, String, Boolean) in un thread separato il cui stato apartment è impostato su STA con SetApartmentState. Nell'esempio seguente si usa la seconda tecnica.
Di conseguenza, l'esempio inizia creando un'istanza di un Thread oggetto e passandolo come parametro un metodo ThreadStart PrintXPS. (L'oggetto Il metodo PrintXPS viene definito più avanti nell'esempio. Il thread viene quindi impostato su un apartment a thread singolo. Il solo codice rimanente del metodo Main
avvia il nuovo thread.
La sostanza dell'esempio è nel metodo static
BatchXPSPrinter. Dopo aver creato un server di stampa e una coda, il metodo richiede all'utente una directory contenente file XPS. Dopo aver validato l'esistenza della directory e la presenza di file con estensione xps, il metodo aggiunge ciascuno di questi file alla coda di stampa. L'esempio presuppone che la stampante non sia XPSDrv, quindi passiamo false
all'ultimo parametro del AddJob(String, String, Boolean) metodo. Per questo motivo, il metodo convaliderà il markup XPS nel file prima di tentare di convertirlo nel linguaggio di descrizione della pagina della stampante. Se la convalida non riesce, viene generata un'eccezione. Il codice di esempio intercetta l'eccezione, ne informerà l'utente e quindi procederà per elaborare il file XPS successivo.
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
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 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 Class
Se si usa una stampante XPSDrv, allora è possibile impostare il parametro finale su true
. In tal caso, poiché XPS è il linguaggio di descrizione della pagina della stampante, il metodo invierà il file alla stampante senza convalidarlo o convertirlo in un'altra lingua di descrizione della pagina. Se non si è certi in fase di progettazione se l'applicazione utilizza una stampante XPSDrv, è possibile modificare l'applicazione in modo che legga la proprietà e il IsXpsDevice ramo in base a ciò che trova.
Poiché inizialmente saranno disponibili poche stampanti XPSDrv subito dopo il rilascio di Windows Vista e Microsoft .NET Framework, potrebbe essere necessario travestire una stampante non XPSDrv come stampante XPSDrv. A tale scopo, aggiungere Pipelineconfig.xml all'elenco dei file nella seguente chiave del Registro di sistema del computer che esegue l'applicazione:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Environments\Windows NT x86\Drivers\Version-3\<PseudoXPSPrinter>\DependentFiles
dove <PseudoXPSPrinter> è qualsiasi coda di stampa. Il computer deve quindi essere riavviato.
Questo travestimento ti consentirà di passare true
come parametro finale di AddJob(String, String, Boolean) senza causare un'eccezione, ma poiché <PseudoXPSPrinter> non è davvero una stampante XPSDrv, solo garbage print.
Nota
Per semplicità, l'esempio precedente usa la presenza di un'estensione *.xps come test che un file è XPS. Tuttavia, i file XPS non devono avere questa estensione. IsXPS.exe (isXPS Conformance Tool) è un modo per testare un file per la validità di XPS.
Vedi anche
.NET Desktop feedback