Drucken einer XPS-Datei (WPF .NET)

Manchmal möchten Sie der Druckwarteschlange einen neuen Druckauftrag hinzufügen, ohne ein Druckdialogfeld zu öffnen. Dazu können Sie eine der PrintQueue.AddJob-Methoden verwenden. Gehen Sie folgendermaßen vor:

Wichtig

Der Desktopleitfaden zu .NET 7 und .NET 6 ist in Bearbeitung.

Im folgenden Beispiel verwenden wir die AddJob(String, String, Boolean)-Methode, eine der verschiedenen Überladungen von AddJob, zu:

  • Fügen Sie der Standarddruckwarteschlange einen neuen Druckauftrag für ein XPS-Dokument (XML Paper Specification) hinzu.
  • Benennen Sie den neuen Auftrag.
  • Geben Sie an, ob das XPS-Dokument überprüft werden soll (mithilfe des fastCopy-Parameters).

Bei Verwendung der AddJob(String, String, Boolean)-Methode ist der Wert des fastCopy-Parameters eine wichtige Berücksichtigung:

  • Wenn Sie den fastCopy-Parameter trueauf festlegen, wird die XPS-Überprüfung übersprungen, und der Druckauftrag wird schnell ohne Seitenfortschrittsfeedback gepoolt.
  • Wenn Sie den fastCopy-Parameter auf false festlegen, muss der Thread, der die AddJob-Methode aufruft, einen Einzelthread-Apartmentzustand aufweisen, andernfalls wird eine Ausnahme ausgelöst. Weitere Informationen finden Sie im Abschnitt Hinweise für AddJob(String, String, Boolean).

Hinzufügen neuer Druckaufträge zur Warteschlange

In diesem Beispiel wird der Standardwarteschlange mindestens ein XPS-Dokument hinzugefügt. Der Code führt folgendes aus:

  1. Verwenden Sie Task.Run, um das Blockieren des UI-Threads zu vermeiden, da es keine asynchrone Version von AddJob ist.
  2. Wenn der fastCopy-Parameterwert false ist, führen Sie AddJob(String, String, Boolean) mit einem Einzelthread-Apartmentzustand aus.
  3. Rufen Sie einen Verweis auf den PrintQueue-Standardwert der LocalPrintServer ab.
  4. Rufen Sie AddJob(String, String, Boolean) im Druckwarteschlangenverweis auf, übergeben Sie einen Auftragsnamen, einen XPS-Dokumentpfad und den fastCopy-Parameter.

Wenn die Warteschlange nicht angehalten wird und der Drucker funktioniert, beginnt ein Druckauftrag automatisch mit dem Drucken, wenn er den oberen Rand der Druckwarteschlange erreicht.

Tipp

Um das Dialogfeld Ausgabedatei speichern als beim Hinzufügen eines Druckauftrags zur Standardwarteschlange zu vermeiden, stellen Sie sicher, dass ihr Standarddrucker nicht Microsoft XPS Document Writer, Microsoft Print to PDF oder andere Druck-zu-Datei-Optionen ist.

/// <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

Tipp

Sie können XPS-Dateien auch mithilfe von drucken:

Weitere Informationen finden Sie im Anzeigen eines Druckdialogfelds und der Übersicht über druckbasierte Dokumente.

Weitere Informationen