Postupy: Tisk souborů XPS prostřednictvím kódu programu
Pomocí jedné z přetížených verzí metody AddJob můžete tisknout soubory XPS (XML Paper Specification) bez otevření PrintDialog nebo vlastně jakéhokoli uživatelského rozhraní (UI).
Soubory XPS můžete vytisknout také pomocí mnoha XpsDocumentWriter.Write a XpsDocumentWriter.WriteAsync metod. Další informace naleznete v tématu Tisk dokumentu XPS.
Dalším způsobem tisku XPS je použití PrintDialog.PrintDocument nebo PrintDialog.PrintVisual metod. Viz Vyvolání dialogového okna tisku.
Příklad
Hlavní kroky použití tříparametrové AddJob(String, String, Boolean) metody jsou následující. Následující příklad obsahuje podrobnosti.
Určete, zda je tiskárna typu XPSDrv. Další informace o XPSDrv najdete v části Přehled tisku .
Pokud tiskárna není tiskárnou XPSDrv, nastavte byt vlákna na jedno vlákno.
Vytvořte instanci tiskového serveru a objektu tiskové fronty.
Zavolejte metodu, zadejte název úlohy, soubor, který se má vytisknout, a příznak Boolean označující, zda je tiskárna XPSDrv nebo ne.
Následující příklad ukazuje, jak dávkově vytisknout všechny soubory XPS v adresáři. I když aplikace vyzve uživatele k zadání adresáře, metoda tří parametrů AddJob(String, String, Boolean) nevyžaduje uživatelské rozhraní. Dá se použít v libovolné cestě kódu, kde máte název souboru XPS a cestu, kterou do něj můžete předat.
Tříparametrový AddJob(String, String, Boolean) přetížení AddJob musí běžet v jednom vláknovém apartmánu, kdykoli je parametr Booleanfalse
, který musí být při použití tiskárny mimo XPSDrv. Výchozí model úloh pro .NET je však multithreaded. Toto výchozí nastavení musí být změněno, protože v příkladu se předpokládá tiskárna, která není XPSDrv.
Výchozí nastavení můžete změnit dvěma způsoby. Jedním ze způsobů je jednoduše přidat STAThreadAttribute (tedy "[System.STAThreadAttribute()]
") těsně nad první řádek metody Main
aplikace (obvykle "static void Main(string[] args)
"). Mnoho aplikací však vyžaduje, aby metoda Main
měla vícevláknový stav bytu, takže existuje druhá metoda: vložte volání AddJob(String, String, Boolean) do jiného vlákna, jehož stav bytu nastavíte na STA pomocí SetApartmentState. Následující příklad používá tuto druhou techniku.
Proto příklad začíná vytvořením instance objektu Thread a předáním metody PrintXPS jako parametru ThreadStart. (Metoda PrintXPS je definována dále v příkladu.) Dále je vlákno nastaveno na jeden vlákno byt. Jediný zbývající kód metody Main
spustí nové vlákno.
Jádro příkladu je v metodě static
BatchXPSPrinter.PrintXPS. Po vytvoření tiskového serveru a fronty metoda vyzve uživatele, aby zadal adresář obsahující XPS soubory. Po ověření existence adresáře a přítomnosti souborů *.xps v něm metoda přidá každý takový soubor do tiskové fronty. Příklad předpokládá, že tiskárna není XPSDrv, takže předáváme false
poslednímu parametru metody AddJob(String, String, Boolean). Z tohoto důvodu metoda ověří kód XPS v souboru předtím, než se pokusí převést na jazyk popisu stránky tiskárny. Pokud se ověření nezdaří, vyvolá se výjimka. Ukázkový kód zachytí výjimku, upozorní uživatele na ni a pak přejde ke zpracování dalšího souboru XPS.
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
Pokud používáte tiskárnu XPSDrv, můžete nastavit konečný parametr na true
. V takovém případě, protože XPS je jazyk popisu stránky tiskárny, metoda odešle soubor do tiskárny bez ověření nebo převodu do jiného jazyka popisu stránky. Pokud si nejste jistí, zda bude aplikace při návrhu používat tiskárnu XPSDrv, můžete ji upravit tak, aby četla vlastnost IsXpsDevice a rozhodla se podle toho, co zjistí.
Vzhledem k tomu, že bude zpočátku k dispozici jen málo tiskáren XPSDrv ihned po vydání systému Windows Vista a Microsoft .NET Framework, možná budete muset zamaskovat tiskárnu ne-XPSDrv jako tiskárnu XPSDrv. Uděláte to tak, že do seznamu souborů v následujícím klíči registru počítače, na kterém běží vaše aplikace, přidejte Pipelineconfig.xml:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Environments\Windows NT x86\Drivers\Version-3\<PseudoXPSPrinter>\DependentFiles
kde <PseudoXPSPrinter> je libovolná tisková fronta. Počítač se pak musí restartovat.
Tento převlek vám umožní předat true
jako konečný parametr AddJob(String, String, Boolean), aniž by to způsobilo výjimku, ale protože <PseudoXPSPrinter> není ve skutečnosti tiskárna XPSDrv, vytiskne se pouze neplatný obsah.
Poznámka
Pro zjednodušení výše uvedený příklad používá přítomnost přípony *.xps jako test, že soubor je XPS. Soubory XPS však nemusí mít tuto příponu. isXPS.exe (isXPS Conformance Tool) je jedním ze způsobů, jak otestovat platnost souboru pro XPS.
Viz také
- PrintQueue
- AddJob
- ApartmentState
- STAThreadAttribute
- dokumentů XPS
- tisk dokumentu XPS
- spravované a nespravované vlákna
- isXPS.exe (nástroj isXPS Conformance Tool)
- dokumenty ve WPF
- #Přehled tisku
.NET Desktop feedback