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

In Windows 8.1 können UWP-Geräte-Apps für Drucker Druckaufträge verwalten. In diesem Thema wird anhand der C#-Version des Beispiels Druckauftragsverwaltung und Druckerwartung gezeigt, 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 UWP-Geräte-Apps kennenlernen.

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. Um mit Bidi zu arbeiten, verwendet das Beispiel die Druckererweiterungsbibliothek im PrinterExtensionLibrary-Projekt . 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 führt im v4-Druckertreiber neue Druckererweiterungsschnittstellen ein, die Sie zum Verwalten von Druckaufträgen verwenden können: IPrinterQueue2, IPrinterQueueView, IPrinterQueueViewEvent, IPrintJob und 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).

Voraussetzungen

Bevor Sie beginnen:

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

  2. Richten Sie Ihren Entwicklungs-PC ein. Informationen zum Herunterladen der Tools und zum Erstellen eines Entwicklerkontos finden Sie unter Erste Schritte.

  3. Verknüpfen Sie Ihre App mit dem Store. Weitere 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 in Erstellen von Gerätemetadaten .

  5. Erstellen Sie die Benutzeroberfläche für die Standard Seite 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. Wenn Sie Ihre App mit C# oder JavaScript schreiben, fügen Sie der UWP-Geräte-App-Lösung das PrinterExtensionLibrary-Projekt hinzu. Dieses Projekt finden Sie im Druckauftragsverwaltungs- und Drucker-Standard-Beispiel.

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 des Druckers

Bevor Ihre App Druckaufträge verwalten kann, muss sie zuerst den Drucker mit den Druckaufträgen suchen. Dazu enthält das Druckauftragsverwaltungs- und Drucker-Standard Tenancebeispiel eine 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.

Dieses Beispiel zeigt die EnumeratePrinters_Click Methode in der Datei PrintJobManagement.xaml.cs . 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);
    }
}

Weitere Informationen zu den PrinterEnumeration und PrinterInfo Klassen finden Sie in der PrinterEnumeration.cs Datei.

Schritt 2: Abrufen der Druckerwarteschlange

Nachdem Sie den Drucker mit den Druckaufträgen identifiziert haben, die Sie verwalten möchten, erstellen Sie eine Ansicht der Druckaufträge mit einem Objekt basierend auf der IPrinterQueueView Schnittstelle (definiert in der PrinterExtensionTypes.cs Datei des PrinterExtensionLibrary-Projekts ). Im Druckauftragsverwaltungs- und Drucker-Standard Einstellungsbeispiel 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.

Dieses Beispiel zeigt die Printer_SelectionChanged Methode in der Datei PrintJobManagement.xaml.cs . 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. Die Auflistung wird über das PrinterQueueViewEventArgs Objekt an die Methode übergeben, das in der PrinterExtensionTypes.cs Datei definiert ist.

Dieses Beispiel zeigt die OnPrinterQueueViewChanged Methode in der Datei PrintJobManagement.xaml.cs .

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 Beispiel Druckauftragsverwaltung und Druckerwartung wird der Druckauftragsstatus jedes Mal angezeigt, wenn ein anderer Druckauftrag ausgewählt wird. Diese Aktualisierung wird von der PrintJob_SelectionChanged Methode durchgeführt.

Dieses Beispiel zeigt die PrintJob_SelectionChanged Methode in der Datei PrintJobManagement.xaml.cs . 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.

Dieses Beispiel zeigt die DisplayablePrintJobStatus Klasse in der Datei PrintJobManagement.xaml.cs . 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 CancelPrintJob_Click-Methode des Beispiels demonstriert.

Dieses Beispiel zeigt die CancelPrintJob_Click Methode in der Datei PrintJobManagement.xaml.cs .

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);
    }
}

Testen

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 keine Gerätemetadaten haben, können Sie diese mit dem Assistenten zum Erstellen von Gerätemetadaten erstellen, wie im Thema Gerätemetadaten für Ihre UWP-Geräte-App erstellen 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ätedaten aus %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, indem Sie auf DeviceMetadataWizard.exe doppelklicken.

    2. Wählen Sie im Menü "Extras " die Option "Testsignatur aktivieren" aus.

  2. Starten Sie den Computer neu.

  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 den Drucker. 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 Device Metadata Authoring Wizard noch nicht geöffnet ist, starten Sie ihn unter %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, indem Sie auf DeviceMetadataWizard.exe doppelklicken.

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

    3. Suchen Sie im Dialogfeld Öffnen das Gerätemetadatenpaket, das Ihrer UWP-Geräte-App zugeordnet ist. (Es verfügt über die Dateierweiterung devicemetadata-ms.)

    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, Herausgebernamen und UWP app ID einzugeben.

    5. Wenn Ihre App für Druckerbenachrichtigungen registriert ist, füllen Sie das Benachrichtigungshandlerfeld aus. Geben Sie in der Ereignis-ID den Namen des Druckereignishandlers ein. Geben Sie in "Event Asset" den Namen der Datei ein, in der sich dieser Code befindet.

    6. Wenn Sie fertig sind, klicken Sie auf Weiter , bis Sie zur Seite Fertig stellen gelangen.

    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". Klicken Sie anschließend auf Speichern.

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

Auftragsverwaltung (v4-Druckertreiber)

Entwickeln von v4-Drucktreibern

Bidirektionale Kommunikationen

Erste Schritte mit UWP-Apps

Erstellen einer UWP-Geräte-App (schrittweise Anleitung)

Erstellen von Gerätemetadaten für eine UWP-Geräte-App (schrittweise Anleitung)