XPS ファイルを印刷する方法 (WPF .NET)

印刷ダイアログ ボックスを開かずに、印刷キューに新しい印刷ジョブを追加する必要がある場合があります。 次のいずれかの PrintQueue.AddJob メソッドを使用して、これを行うことができます。 ここではその方法を説明します。

重要

.NET 7 と .NET 6 用のデスクトップ ガイド ドキュメントは作成中です。

次の例では、AddJob(String, String, Boolean) メソッド (AddJob のいくつかのオーバーロードの 1 つ) を使用して、以下のことを行います。

  • 既定の印刷キューに、XML Paper Specification (XPS) ドキュメントの新しい印刷ジョブを追加する。
  • 新しいジョブに名前を付ける。
  • (fastCopy パラメーターを使用して) XPS ドキュメントを検証するかどうかを指定する。

AddJob(String, String, Boolean) メソッドを使用する場合は、fastCopy パラメーターの値が重要な考慮事項となります。

  • fastCopy パラメーターを true に設定すると、XPS 検証はスキップされ、印刷ジョブはページごとの進行状況フィードバックなしですばやくスプールされます。
  • fastCopy パラメーターを false に設定した場合、AddJob メソッドを呼び出すスレッドはシングルスレッド アパートメント状態である必要があります。それ以外の場合は、例外がスローされます。 詳細については、「AddJob(String, String, Boolean)」の「解説」セクションを参照してください。

新しい印刷ジョブをキューに追加する

この例では、1 つまたは複数の XPS ドキュメントを既定のキューに追加します。 コードで次のことを行います。

  1. AddJob の非同期バージョンがないので、UI スレッドがブロックされるのを回避するために Task.Run を使用します。
  2. fastCopy パラメーター値が false の場合は、シングルスレッド アパートメント状態のスレッドで AddJob(String, String, Boolean) を実行します。
  3. LocalPrintServer の既定の PrintQueue への参照を取得します。
  4. 印刷キュー参照で AddJob(String, String, Boolean) を呼び出し、ジョブ名、XPS ドキュメント パス、および fastCopy パラメーターを渡します。

キューが一時停止されておらず、プリンターが動作している場合、印刷ジョブでは印刷キューの先頭に達したときに自動的に印刷が開始されます。

ヒント

既定のキューに印刷ジョブを追加するときに [Save Output File As](出力ファイルを名前を付けて保存) ダイアログが表示されないようにするには、確実に既定のプリンターが Microsoft XPS Document WriterMicrosoft PDF 印刷、あるいはその他の "ファイルへ出力" オプションにしないようにします。

/// <summary>
/// Asyncronously, add a batch of XPS documents to the print queue using a PrintQueue.AddJob method.
/// Handle the thread apartment state required by the PrintQueue.AddJob method.
/// </summary>
/// <param name="xpsFilePaths">A collection of XPS documents.</param>
/// <param name="fastCopy">Whether to validate the XPS documents.</param>
/// <returns>Whether all documents were added to the print queue.</returns>
public static async Task<bool> BatchAddToPrintQueueAsync(IEnumerable<string> xpsFilePaths, bool fastCopy = false)
{
    bool allAdded = true;

    // Queue some work to run on the ThreadPool.
    // Wait for completion without blocking the calling thread.
    await Task.Run(() =>
    {
        if (fastCopy)
            allAdded = BatchAddToPrintQueue(xpsFilePaths, fastCopy);
        else
        {
            // Create a thread to call the PrintQueue.AddJob method.
            Thread newThread = new(() =>
            {
                allAdded = BatchAddToPrintQueue(xpsFilePaths, fastCopy);
            });

            // Set the thread to single-threaded apartment state.
            newThread.SetApartmentState(ApartmentState.STA);

            // Start the thread.
            newThread.Start();

            // Wait for thread completion. Blocks the calling thread,
            // which is a ThreadPool thread.
            newThread.Join();
        }
    });

    return allAdded;
}

/// <summary>
/// Add a batch of XPS documents to the print queue using a PrintQueue.AddJob method.
/// </summary>
/// <param name="xpsFilePaths">A collection of XPS documents.</param>
/// <param name="fastCopy">Whether to validate the XPS documents.</param>
/// <returns>Whether all documents were added to the print queue.</returns>
public static bool BatchAddToPrintQueue(IEnumerable<string> xpsFilePaths, bool fastCopy)
{
    bool allAdded = true;

    // To print without getting the "Save Output File As" dialog, ensure
    // that your default printer is not the Microsoft XPS Document Writer,
    // Microsoft Print to PDF, or other print-to-file option.

    // Get a reference to the default print queue.
    PrintQueue defaultPrintQueue = LocalPrintServer.GetDefaultPrintQueue();

    // Iterate through the document collection.
    foreach (string xpsFilePath in xpsFilePaths)
    {
        // Get document name.
        string xpsFileName = Path.GetFileName(xpsFilePath);

        try
        {
            // The AddJob method adds a new print job for an XPS
            // document into the print queue, and assigns a job name.
            // Use fastCopy to skip XPS validation and progress notifications.
            // If fastCopy is false, the thread that calls PrintQueue.AddJob
            // must have a single-threaded apartment state.
            PrintSystemJobInfo xpsPrintJob =
                    defaultPrintQueue.AddJob(jobName: xpsFileName, documentPath: xpsFilePath, fastCopy);

            // If the queue is not paused and the printer is working, then jobs will automatically begin printing.
            Debug.WriteLine($"Added {xpsFileName} to the print queue.");
        }
        catch (PrintJobException e)
        {
            allAdded = false;
            Debug.WriteLine($"Failed to add {xpsFileName} to the print queue: {e.Message}\r\n{e.InnerException}");
        }
    }

    return allAdded;
}
''' <summary>
''' Asyncronously, add a batch of XPS documents to the print queue using a PrintQueue.AddJob method.
''' Handle the thread apartment state required by the PrintQueue.AddJob method.
''' </summary>
''' <param name="xpsFilePaths">A collection of XPS documents.</param>
''' <param name="fastCopy">Whether to validate the XPS documents.</param>
''' <returns>Whether all documents were added to the print queue.</returns>
Public Shared Async Function BatchAddToPrintQueueAsync(xpsFilePaths As IEnumerable(Of String), Optional fastCopy As Boolean = False) As Task(Of Boolean)

    Dim isAllPrinted As Boolean = True

    ' Queue some work to run on the ThreadPool.
    ' Wait for completion without blocking the calling thread.
    Await Task.Run(
        Sub()
            If fastCopy Then
                isAllPrinted = BatchAddToPrintQueue(xpsFilePaths, fastCopy)
            Else
                ' Create a thread to call the PrintQueue.AddJob method.
                Dim newThread As New Thread(
                    Sub()
                        isAllPrinted = BatchAddToPrintQueue(xpsFilePaths, fastCopy)
                    End Sub
                )

                ' Set the thread to single-threaded apartment state.
                newThread.SetApartmentState(ApartmentState.STA)

                ' Start the thread.
                newThread.Start()

                ' Wait for thread completion. Blocks the calling thread,
                ' which is a ThreadPool thread.
                newThread.Join()
            End If
        End Sub
    )

    Return isAllPrinted

End Function

''' <summary>
''' Add a batch of XPS documents to the print queue using a PrintQueue.AddJob method.
''' </summary>
''' <param name="xpsFilePaths">A collection of XPS documents.</param>
''' <param name="fastCopy">Whether to validate the XPS documents.</param>
''' <returns>Whether all documents were added to the print queue.</returns>
Public Shared Function BatchAddToPrintQueue(xpsFilePaths As IEnumerable(Of String), fastCopy As Boolean) As Boolean

    Dim isAllPrinted As Boolean = True

    ' To print without getting the "Save Output File As" dialog, ensure
    ' that your default printer is not the Microsoft XPS Document Writer,
    ' Microsoft Print to PDF, or other print-to-file option.

    ' Get a reference to the default print queue.
    Dim defaultPrintQueue As PrintQueue = LocalPrintServer.GetDefaultPrintQueue()

    ' Iterate through the document collection.
    For Each xpsFilePath As String In xpsFilePaths

        ' Get document name.
        Dim xpsFileName As String = Path.GetFileName(xpsFilePath)

        Try
            ' The AddJob method adds a new print job for an XPS
            ' document into the print queue, and assigns a job name.
            ' Use fastCopy to skip XPS validation and progress notifications.
            ' If fastCopy is false, the thread that calls PrintQueue.AddJob
            ' must have a single-threaded apartment state.
            Dim xpsPrintJob As PrintSystemJobInfo = defaultPrintQueue.AddJob(jobName:=xpsFileName, documentPath:=xpsFilePath, fastCopy)

            ' If the queue is not paused and the printer is working, then jobs will automatically begin printing.
            Debug.WriteLine($"Added {xpsFileName} to the print queue.")
        Catch e As PrintJobException
            isAllPrinted = False
            Debug.WriteLine($"Failed to add {xpsFileName} to the print queue: {e.Message}\r\n{e.InnerException}")
        End Try
    Next

    Return isAllPrinted

End Function

ヒント

また、以下を使用して XPS ファイルを印刷することもできます。

詳細については、「印刷ダイアログ ボックスを表示する方法」および「ドキュメント印刷の概要」を参照してください。

関連項目