Freigeben über


Verwalten von Druckaufträgen in einer UWP-Geräte-App

Important

Geräte-Metadaten sind veraltet und werden in einer zukünftigen Version von Windows entfernt. Informationen zum Ersatz dieser Funktionalität finden Sie unter Treiberpaketcontainermetadaten.

In Windows 8.1 können UWP-Geräte-Apps für Drucker Druckaufträge verwalten. In diesem Thema wird die C#-Version der Druckauftragsverwaltung und druckerwartung verwendet, um zu veranschaulichen, wie Sie eine Ansicht von Druckaufträgen erstellen, diese Aufträge überwachen und bei Bedarf einen Auftrag abbrechen. Weitere Informationen zu UWP-Geräte-Apps im Allgemeinen finden Sie unter "Treffen von UWP-Geräte-Apps".

Die C#-Version der Druckauftragsverwaltung und des Druckers Standard Tenance-Beispiel veranschaulicht die Standard stellung des Druckers mit der Datei DeviceMaintenance.xaml.cs im DeviceAppForPrinters2-Projekt. To work with Bidi, the sample uses the printer extension library in the PrinterExtensionLibrary project. Die Druckererweiterungsbibliothek bietet eine bequeme Möglichkeit, auf die Druckererweiterungsschnittstellen des v4-Drucktreibers zuzugreifen. Weitere Informationen finden Sie in der Übersicht über die Druckererweiterungsbibliothek.

Die in diesem Thema gezeigten Codebeispiele basieren auf der C#-Version des Beispiels Druckauftragsverwaltung und Druckerwartung. Dieses Beispiel ist auch in JavaScript und C++ verfügbar. Da C++ direkt auf COM zugreifen kann, enthält die C++-Version des Beispiels keine Codebibliotheksprojekte. Laden Sie die Beispiele herunter, um die neuesten Versionen des Codes anzuzeigen.

Verwalten von Druckaufträgen

Windows 8.1 introduces new printer extension interfaces in the v4 printer driver that you can use for managing print jobs: IPrinterQueue2, IPrinterQueueView, IPrinterQueueViewEvent, IPrintJob, and IPrintJobCollection. Diese Schnittstellen ermöglichen das Überwachen und Abbrechen von Druckaufträgen. Weitere Informationen finden Sie unter Druckauftragsverwaltung (v4 Druckertreiber).

C#- und JavaScript-Apps können nicht direkt mit COM-APIs arbeiten. Wenn Sie eine C#- oder JavaScript-UWP-Geräte-App schreiben, verwenden Sie die Druckererweiterungsbibliothek, um auf diese Schnittstellen zuzugreifen (wie in diesem Thema gezeigt).

Prerequisites

Bevor Sie beginnen:

  1. Stellen Sie sicher, dass Ihr Drucker mit einem v4-Drucktreiber installiert ist. Weitere Informationen finden Sie unter Entwickeln von v4-Drucktreibern.

  2. Richten Sie Ihren Entwicklungs-PC ein. See Getting started for info about downloading the tools and creating a developer account.

  3. Ordnen Sie Ihre App dem Store zu. Informationen hierzu finden Sie unter Erstellen einer UWP-Geräte-App .

  4. Erstellen Sie Gerätemetadaten für Ihren Drucker, der sie Ihrer App zuordnet. Weitere Informationen hierzu finden Sie unter Erstellen von Gerätemetadaten .

  5. Erstellen Sie die Benutzeroberfläche für die Hauptseite Ihrer App. Alle UWP-Geräte-Apps können von "Start" gestartet werden, wo sie im Vollbildmodus angezeigt werden. Verwenden Sie die Startoberfläche, um Ihr Produkt oder Ihre Dienste auf eine Weise hervorzuheben, die den spezifischen Branding- und Features Ihrer Geräte entspricht. Es gibt keine besonderen Einschränkungen für den Typ der UI-Steuerelemente, die sie verwenden können. Informationen zu den ersten Schritten mit dem Design der Vollbildoberfläche finden Sie in den Microsoft Store-Designprinzipien.

  6. If you're writing your app with C# or JavaScript, add the PrinterExtensionLibrary project to your UWP device app solution. Dieses Projekt finden Sie im Beispiel für Druckauftragsverwaltung und Druckerwartung.

Da C++ direkt auf COM zugreifen kann, benötigen C++-Apps keine separate Bibliothek, um mit dem COM-basierten Druckergerätekontext zu arbeiten.

Schritt 1: Suchen nach Druckern

Bevor Ihre App Druckaufträge verwalten kann, muss sie zuerst den Drucker mit den Druckaufträgen suchen. Dazu enthält das Druckauftragsverwaltungs- und Druckerwartungsbeispiel eine praktische Klasse namens PrinterEnumeration (in der PrinterEnumeration.cs Datei). Diese Klasse findet alle Drucker, die Ihrer App über Gerätemetadaten zugeordnet sind, und gibt eine Liste von PrinterInfo Objekten zurück, die die Namen und Geräte-IDs für jeden Drucker enthält.

This example shows the EnumeratePrinters_Click method in the PrintJobManagement.xaml.cs file. Es zeigt, wie das Beispiel die PrinterEnumeration Klasse verwendet, um eine Liste der zugeordneten Drucker abzurufen.

private async void EnumeratePrinters_Click(object sender, RoutedEventArgs e)
{
    try
    {
        rootPage.NotifyUser("Enumerating printers. Please wait", NotifyType.StatusMessage);

        // Retrieve the running app's package family name, and enumerate associated printers.
        string currentPackageFamilyName = Windows.ApplicationModel.Package.Current.Id.FamilyName;

        // Enumerate associated printers.
        PrinterEnumeration pe = new PrinterEnumeration(currentPackageFamilyName);
        List<PrinterInfo> associatedPrinters = await pe.EnumeratePrintersAsync();

        // Update the data binding source on the combo box that displays the list of printers.
        PrinterComboBox.ItemsSource = associatedPrinters;
        if (associatedPrinters.Count > 0)
        {
            PrinterComboBox.SelectedIndex = 0;
            rootPage.NotifyUser(associatedPrinters.Count + " printers enumerated", NotifyType.StatusMessage);
        }
        else
        {
            rootPage.NotifyUser(DisplayStrings.NoPrintersEnumerated, NotifyType.ErrorMessage);
        }
    }
    catch (Exception exception)
    {
        rootPage.NotifyUser("Caught an exception: " + exception.Message, NotifyType.ErrorMessage);
    }
}

For more info about the PrinterEnumeration and PrinterInfo classes, see the PrinterEnumeration.cs file.

Schritt 2: Abrufen der Druckerwarteschlange

Once you've identified the printer having the print jobs that you want to manage, create a view of the print jobs, with object based on the IPrinterQueueView interface (defined in the PrinterExtensionTypes.cs file of the PrinterExtensionLibrary project). Im Druckauftragsverwaltungs- und Druckerwartungsbeispiel wird dieses Objekt benannt currentPrinterQueueView und jedes Mal neu erstellt, wenn sich die Druckerauswahl ändert.

In der Printer_SelectionChanged Methode verwendet das Beispiel zunächst ein PrinterInfo Objekt zum Erstellen eines Druckererweiterungskontextobjekts mit dem Namen context. Anschließend wird die GetPrinterQueueView Methode zum context Erstellen des currentPrinterQueueView Objekts verwendet. Schließlich wird ein Ereignishandler zum Behandeln des currentPrinterQueueViewEreignisses OnChanged hinzugefügt.

This example shows the Printer_SelectionChanged method in the PrintJobManagement.xaml.cs file. Es zeigt, wie Sie ein Druckerwarteschlangenansichtsobjekt basierend auf IPrinterQueueView.

private void Printer_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    try
    {
        // Remove the current printer queue view (if any) before displaying the new view.
        if (currentPrinterQueueView != null)
        {
            currentPrinterQueueView.OnChanged -= OnPrinterQueueViewChanged;
            currentPrinterQueueView = null;
        }

        // Retrieve a COM IPrinterExtensionContext object, using the static WinRT factory.
        // Then instantiate one "PrinterExtensionContext" object that allows operations on the COM object.
        PrinterInfo queue = (PrinterInfo)PrinterComboBox.SelectedItem;
        Object comContext = Windows.Devices.Printers.Extensions.PrintExtensionContext.FromDeviceId(queue.DeviceId);
        PrinterExtensionContext context = new PrinterExtensionContext(comContext);

        // Display the printer queue view.
        const int FirstPrintJobEnumerated = 0;
        const int LastPrintJobEnumerated = 10;

        currentPrinterQueueView = context.Queue.GetPrinterQueueView(FirstPrintJobEnumerated, LastPrintJobEnumerated);
        currentPrinterQueueView.OnChanged += OnPrinterQueueViewChanged;
    }
    catch (Exception exception)
    {
        rootPage.NotifyUser("Caught an exception: " + exception.Message, NotifyType.ErrorMessage);
    }
}

Außerdem ruft ein Ereignishandler bei jeder Änderung der Ansicht der Druckaufträge die OnPrinterQueueViewChanged Methode auf. Diese Methode ist für die erneute Bindung mit PrintJobListBox einer IEnumerable-Auflistung von IPrintJob Objekten verantwortlich. The collection is passed to the method via the PrinterQueueViewEventArgs object, which is defined in the PrinterExtensionTypes.cs file.

This example shows the OnPrinterQueueViewChanged method in the PrintJobManagement.xaml.cs file.

private async void OnPrinterQueueViewChanged(object sender, PrinterQueueViewEventArgs e)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        // Update the data binding on the ListBox that displays print jobs.
        PrintJobListBox.ItemsSource = e.Collection;
        if (PrintJobListBox.Items.Count > 0)
        {
            // If there are print jobs in the current view, mark the first job as selected.
            PrintJobListBox.SelectedIndex = 0;
        }
    });
}

Schritt 3: Anzeigen des Druckauftragsstatus

Da die PrintJobListBox Bindung an eine Auflistung von IPrintJob Objekten erfolgt, ist das Anzeigen des Status eines Auftrags relativ einfach. Der ausgewählte Druckauftrag wird als IPrintJob Objekt umgewandelt, und dann werden die Eigenschaften dieses Objekts verwendet, um das PrintJobDetails TextBox-Objekt auszufüllen.

Im Druckauftragsverwaltungs- und Druckerwartungsbeispiel wird der Druckauftragsstatus jedes Mal angezeigt, wenn ein anderer Druckauftrag ausgewählt wird. Diese Aktualisierung wird von der PrintJob_SelectionChanged Methode durchgeführt.

This example shows the PrintJob_SelectionChanged method in the PrintJobManagement.xaml.cs file. Es zeigt, wie der Status eines Druckauftrags basierend auf einem IPrintJob Objekt angezeigt wird.

private void PrintJob_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    try
    {
        // Display details of the selected print job.
        IPrintJob job = (IPrintJob)PrintJobListBox.SelectedItem;
        if (job != null)
        {
            PrintJobDetails.Text =
                "Details of print job: " + job.Name + "\r\n" +
                "Pages printed: " + job.PrintedPages + "/" + job.TotalPages + "\r\n" +
                "Submission time: " + job.SubmissionTime + "\r\n" +
                "Job status: " + DisplayablePrintJobStatus.ToString(job.Status);
        }
        else
        {
            PrintJobDetails.Text = "Please select a print job";
        }
    }
    catch (Exception exception)
    {
        rootPage.NotifyUser("Caught an exception: " + exception.Message, NotifyType.ErrorMessage);
    }
}

Um die Statusbeschreibung des Druckauftrags anzuzeigen, verwendet die PrintJob_SelectionChanged Methode ein statisches Wörterbuch mit dem Namen printJobStatusDisplayNames, um Auftragsstatusbeschreibungen anzuzeigen, die sich in einem benutzerfreundlichen Textformat befinden.

This example shows the DisplayablePrintJobStatus class in the PrintJobManagement.xaml.cs file. Diese Klasse enthält die statischen Member, die von der PrintJob_SelectionChanged.

internal class DisplayablePrintJobStatus
{
    /// <summary>
    /// Converts the PrintJobStatus bit fields to a display string.
    /// </summary>
    internal static string ToString(PrintJobStatus printJobStatus)
    {
        StringBuilder statusString = new StringBuilder();

        // Iterate through each of the PrintJobStatus bits that are set and convert it to a display string.
        foreach (var printJobStatusDisplayName in printJobStatusDisplayNames)
        {
            if ((printJobStatusDisplayName.Key & printJobStatus) != 0)
            {
                statusString.Append(printJobStatusDisplayName.Value);
            }
        }

        int stringlen = statusString.Length;
        if (stringlen > 0)
        {
            // Trim the trailing comma from the string.
            return statusString.ToString(0, stringlen - 1);
        }
        else
        {
            // If no print job status field was set, display "Not available".
            return "Not available";
        }
    }

    /// <summary>
    /// Static constructor that initializes the display name for the PrintJobStatus field.
    /// </summary>
    static DisplayablePrintJobStatus()
    {
        printJobStatusDisplayNames = new Dictionary<PrintJobStatus, string>();

        printJobStatusDisplayNames.Add(PrintJobStatus.Paused, "Paused,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Error, "Error,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Deleting, "Deleting,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Spooling, "Spooling,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Printing, "Printing,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Offline, "Offline,");
        printJobStatusDisplayNames.Add(PrintJobStatus.PaperOut, "Out of paper,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Printed, "Printed,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Deleted, "Deleted,");
        printJobStatusDisplayNames.Add(PrintJobStatus.BlockedDeviceQueue, "Blocked device queue,");
        printJobStatusDisplayNames.Add(PrintJobStatus.UserIntervention, "User intervention required,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Restarted, "Restarted,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Complete, "Complete,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Retained, "Retained,");
    }
    
    /// <summary>
    /// Private constructor to prevent default instantiation.
    /// </summary>
    private DisplayablePrintJobStatus() { }

    /// <summary>
    /// Contains the mapping between PrintJobStatus fields and display strings.
    /// </summary>
    private static Dictionary<PrintJobStatus, string> printJobStatusDisplayNames;
}

Schritt 4: Abbrechen des Druckauftrags

Ähnlich wie beim Anzeigen des Druckauftragsstatus ist das Abbrechen eines Druckauftrags relativ einfach, wenn Sie über ein IPrintJob Objekt verfügen. Die IPrintJob Klasse stellt eine RequestCancel Methode bereit, die den Abbruch des entsprechenden Druckauftrags initiiert. Dies wird in der Methode des Beispiels CancelPrintJob_Click veranschaulicht.

This example shows the CancelPrintJob_Click method in the PrintJobManagement.xaml.cs file.

private void CancelPrintJob_Click(object sender, RoutedEventArgs e)
{
    try
    {
        IPrintJob job = (IPrintJob)PrintJobListBox.SelectedItem;
        job.RequestCancel();
    }
    catch (Exception exception)
    {
        rootPage.NotifyUser("Caught an exception: " + exception.Message, NotifyType.ErrorMessage);
    }
}

Testing

Bevor Sie Ihre UWP-Geräte-App testen können, muss sie mithilfe von Gerätemetadaten mit Ihrem Drucker verknüpft werden.

Sie benötigen eine Kopie des Gerätemetadatenpakets für Ihren Drucker, um die Geräte-App-Informationen hinzuzufügen. Wenn Sie nicht über Gerätemetadaten verfügen, können Sie sie mit dem Assistenten für die Erstellung von Gerätemetadaten erstellen, wie im Thema "Erstellen von Gerätemetadaten für Ihre UWP-Geräte-App" beschrieben.

Um den Assistenten zum Erstellen von Gerätemetadaten zu verwenden, müssen Sie Microsoft Visual Studio Professional, Microsoft Visual Studio Ultimate oder das eigenständige SDK für Windows 8.1 installieren, bevor Sie die Schritte in diesem Thema ausführen. Beim Installieren von Microsoft Visual Studio Express für Windows wird eine Version des SDK installiert, die den Assistenten nicht enthält.

Die folgenden Schritte erstellen Ihre App und installieren die Gerätemetadaten.

  1. Aktivieren Sie die Testsignatur.

    1. Starten Sie den Assistenten für die Erstellung von Gerätemetadaten aus %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, indem Sie auf DeviceMetadataWizard.exe doppelklicken.

    2. From the Tools menu, select Enable Test Signing.

  2. Neustarten des Computers

  3. Erstellen Sie die Lösung, indem Sie die Lösungsdatei (.sln) öffnen. Drücken Sie F7 oder gehen Sie im oberen Menü zu Build->Build Solution, nachdem das Beispiel geladen wurde.

  4. Trennen Sie den Drucker und deinstallieren Sie ihn. Dieser Schritt ist erforderlich, damit Windows die aktualisierten Gerätemetadaten beim nächsten Erkennen des Geräts liest.

  5. Bearbeiten und Speichern von Gerätemetadaten Um die Geräte-App mit Ihrem Gerät zu verknüpfen, müssen Sie die Geräte-App Ihrem Gerät zuordnen.

    Wenn Sie Ihre Gerätemetadaten noch nicht erstellt haben, lesen Sie " Erstellen von Gerätemetadaten für Ihre UWP-Geräte-App".

    1. Wenn der Assistent für die Erstellung von Gerätemetadaten noch nicht geöffnet ist, starten Sie ihn von %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, indem Sie auf DeviceMetadataWizard.exedoppelklicken.

    2. Klicken Sie auf "Gerätemetadaten bearbeiten". Dadurch können Sie Ihr vorhandenes Gerätemetadatenpaket bearbeiten.

    3. In the Open dialog box, locate the device metadata package associated with your UWP device app. (It has a devicemetadata-ms file extension.)

    4. Geben Sie auf der Seite " Informationen zur UWP-Geräte-App angeben " die Informationen zur Microsoft Store-App in das Feld "UWP-Geräte-App " ein. Klicken Sie auf "UWP-App-Manifestdatei importieren", um automatisch den Paketnamen, den Herausgebernamen und die UWP-App-ID einzugeben.

    5. If your app is registering for printer notifications, fill out the Notification handlers box. In Event ID, enter the name of the print event handler. In Event Asset, enter the name of the file where that code resides.

    6. When you're done, click Next until you get to the Finish page.

    7. Vergewissern Sie sich auf der Seite " Überprüfen des Gerätemetadatenpakets ", dass alle Einstellungen korrekt sind, und aktivieren Sie das Kontrollkästchen "Gerätemetadatenpaket in den Metadatenspeicher auf dem lokalen Computer kopieren ". Then click Save.

  6. Verbinden Sie den Drucker erneut, damit Windows die aktualisierten Gerätemetadaten liest, wenn das Gerät verbunden ist.