方法 : XPS ファイルをプログラムにより印刷する
更新 : 2007 年 11 月
AddJob メソッドの 1 つのオーバーロードを使用すると、PrintDialog や、原則としてはその他のユーザー インターフェイス (UI) を一切開くことなく、XML Paper Specification (XPS) ファイルを印刷することができます。
また、XpsDocumentWriter の多くの Write メソッドや WriteAsync メソッドを使用して、XML Paper Specification (XPS) ファイルを印刷することもできます。この詳細については、「XPS ドキュメントの印刷」を参照してください。
XML Paper Specification (XPS) の印刷は、PrintDialog コントロールの PrintDocument メソッドまたは PrintVisual メソッドを使用しても実行できます。「方法 : 印刷ダイアログ ボックスを呼び出す」を参照してください。
使用例
3 つのパラメータをとる AddJob(String, String, Boolean) メソッドを使用する主な手順は次のとおりです。詳細は、下記の例に示します。
プリンタが XPSDrv プリンタであるかどうかを確認します (XPSDrv の詳細については、「印刷の概要」を参照してください)。
プリンタが XPSDrv プリンタでない場合は、スレッドのアパートメントをシングル スレッドに設定します。
プリント サーバーと印刷キューのオブジェクトをインスタンス化します。
ジョブ名、印刷するファイル、およびプリンタが XPSDrv プリンタであるかどうかを示す Boolean フラグを指定して、メソッドを呼び出します。
ディレクトリ内のすべての XPS ファイルをバッチ印刷する方法を次の例に示します。アプリケーションはユーザーにディレクトリの指定を求めますが、3 つのパラメータをとる AddJob(String, String, Boolean) メソッドはユーザー インターフェイス (UI) を必要としません。このメソッドは、そのメソッドに渡すことができる XPS ファイル名とパスが記述された任意のコード パスで使用できます。
AddJob の 3 つのパラメータをとる AddJob(String, String, Boolean) オーバーロードは、Boolean パラメータが false の場合 (XPSDrv 以外のプリンタが使用されている場合) は必ずシングル スレッドで実行する必要があります。ただし、Microsoft .NET の既定のアパートメントの状態は、マルチ スレッドです。この例では XPSDrv 以外のプリンタを前提にしているため、この既定の状態を逆にする必要があります。
既定の状態を変更する方法は 2 つあります。1 つは、単純に STAThreadAttribute (つまり "[System.STAThreadAttribute()]") をアプリケーションの Main メソッド (通常は "static void Main(string[] args)") のすぐ上に追加する方法です。ただし、多くのアプリケーションは、Main メソッドのアパートメントの状態がマルチ スレッドであることを必要とするため、もう 1 つの方法が用意されています。それは、AddJob(String, String, Boolean) の呼び出しを、そのアパートメントの状態が SetApartmentState で STA に設定されている個別のスレッドで行う方法です。次に示す例では、この 2 番目の方法を使用します。
したがって、この例では、最初に Thread オブジェクトをインスタンス化し、そのオブジェクトを PrintXPS メソッドに ThreadStart パラメータとして渡します (PrintXPS メソッドは例の後半で定義されます)。次に、そのスレッドをシングル スレッド アパートメントに設定します。それ以降の Main メソッドのコードでは、この新しいスレッドを開始します。
この例の要点は、staticBatchXPSPrinter.PrintXPS メソッド内にあります。プリント サーバーとキューを作成した後、このメソッドによって、XPS ファイルを含むディレクトリの指定を求めるプロンプトが表示されます。ディレクトリの有無と、そのディレクトリに *.xps ファイルがあるかどうかを確認した後に、各ファイルが印刷キューに追加されます。この例では、プリンタが XPSDrv 以外のプリンタであることが前提になっているため、AddJob(String, String, Boolean) メソッドの最後のパラメータに false を渡しています。このため、このメソッドはファイル内の XPS マークアップを検証してから、そのマークアップをプリンタのページ記述言語に変換しようとします。検証に失敗すると、例外がスローされます。このコード例では、その例外をキャッチし、ユーザーに例外の発生を通知してから、次の 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
XPSDrv プリンタを使用している場合は、最後のパラメータを true に設定できます。その場合、XPS はプリンタのページ記述言語であるため、メソッドはファイルの検証や別のページ記述言語への変換を行わずにファイルをプリンタに送ります。アプリケーションが XPSDrv プリンタを使用するかどうかがデザイン時に不明な場合は、IsXpsDevice プロパティを読み込んで、その検出内容に従って分岐するようにアプリケーションを変更できます。
Windows Vista および Microsoft .NET Framework のリリースの直後には XPSDrv プリンタの普及率が低いことが想定されるため、場合によっては、XPSDrv プリンタではないプリンタを XPSDrv プリンタに見せかける必要があります。そのためには、アプリケーションを実行しているコンピュータで、以下のレジストリ キーのファイルの一覧に Pipelineconfig.xml を追加します。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Environments\Windows NT x86\Drivers\Version-3\<PseudoXPSPrinter>\DependentFiles
<PseudoXPSPrinter> は任意の印刷キューです。変更後に、コンピュータを再起動する必要があります。
このように見せかけることで、例外を発生させることなく、AddJob(String, String, Boolean) の最後のパラメータとして true を渡すことができますが、<PseudoXPSPrinter> は実際には XPSDrv プリンタではないため、正しく印刷されません。
メモ 上記の例では、単純化のため、*.xps 拡張子の有無でファイルが XPS かどうかを確認していますが、XPS ファイルには、この拡張子を付ける必要はありません。isXPS 適合性ツールは、ファイルが XPS かどうかをテストする 1 つの手段です。
参照
処理手順
概念
Windows Presentation Foundation のドキュメント