Freigeben über


So zeigen Sie den Druckerstatus in einer UWP-Geräte-App an

In Windows 8.1 können Benutzer ihren Druckerstatus über die moderne Benutzeroberfläche einer UWP-Geräte-App überprüfen. In diesem Thema wird anhand der C#-Version des Beispiels Druckeinstellungen und Druckbenachrichtigungen gezeigt, wie der Druckerstatus abgefragt und angezeigt wird. Weitere Informationen zu UWP-Geräte-Apps im Allgemeinen finden Sie unter UWP-Geräte-Apps kennenlernen.

In der C#-Version der Druckeinstellungen und des Druckbenachrichtigungsbeispiels wird die Seite InkLevel.xaml verwendet, um zu veranschaulichen, wie der Druckerstatus (in diesem Fall die Freihandebene) abgerufen und angezeigt wird. Eine Druckhilfsklasse wird verwendet, um einen Gerätekontext (IPrinterExtensionContext) zu erstellen und die Geräteabfragen durchzuführen. Die PrinterHelperClass.cs-Datei befindet sich im DeviceAppForPrintersLibrary-Projekt und verwendet APIs, die im PrinterExtensionLibrary-Projekt definiert sind. Die Druckererweiterungsbibliothek bietet eine bequeme Möglichkeit, auf die Druckererweiterungsschnittstellen des v4-Drucktreibers zuzugreifen. Weitere Informationen finden Sie in der Übersicht über die Druckererweiterungsbibliothek.

Hinweis

Die in diesem Thema gezeigten Codebeispiele basieren auf der C#-Version der Druckeinstellungen und des Druckbenachrichtigungsbeispiels . 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.

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. Informationen hierzu finden Sie in Schritt 1: 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 Schritt 2: Erstellen von Gerätemetadaten .

  5. Wenn Sie Ihre App mit C# oder JavaScript schreiben, fügen Sie die Projekte PrinterExtensionLibrary und DeviceAppForPrintersLibrary zu Ihrer UWP-Geräte-App-Lösung hinzu. Sie finden jedes dieser Projekte im Beispiel Druckeinstellungen und Druckbenachrichtigungen .

    Hinweis

    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: Drucker lokalisieren

Bevor ein Gerätekontext erstellt werden kann, muss die App die Geräte-ID des Druckers ermitteln. Dazu verwendet das Beispiel die EnumerateAssociatedPrinters-Methode, um alle Drucker zu durchsuchen, die an den PC angeschlossen sind. Anschließend überprüft er den Container für jeden Drucker und sucht nach einer Zuordnung, indem die PackageFamilyName-Eigenschaft jedes Containers verglichen wird.

Hinweis

Der System.Devices.AppPackageFamilyName für Geräte, die Ihrer App zugeordnet sind, finden Sie auf der Registerkarte Packing im Manifest-Designer in Microsoft Visual Studio.

Dieses Beispiel zeigt die EnumerateAssociatedPrinters-Methode aus der Datei InkLevel.xaml.cs :

async void EnumerateAssociatedPrinters(object sender, RoutedEventArgs e)
{
    // Reset output text and associated printer array.
    AssociatedPrinters.Items.Clear();
    BidiOutput.Text = "";

    // GUID string for printers.
    string printerInterfaceClass = "{0ecef634-6ef0-472a-8085-5ad023ecbccd}";
    string selector = "System.Devices.InterfaceClassGuid:=\"" + printerInterfaceClass + "\"";

    // By default, FindAllAsync does not return the containerId for the device it queries.
    // We have to add it as an additional property to retrieve. 
    string containerIdField = "System.Devices.ContainerId";
    string[] propertiesToRetrieve = new string[] { containerIdField };

    // Asynchronously find all printer devices.
    DeviceInformationCollection deviceInfoCollection = await DeviceInformation.FindAllAsync(selector, propertiesToRetrieve);

    // For each printer device returned, check if it is associated with the current app.
    for (int i = 0; i < deviceInfoCollection.Count; i++)
    {
        DeviceInformation deviceInfo = deviceInfoCollection[i];
        FindAssociation(deviceInfo, deviceInfo.Properties[containerIdField].ToString());
    }
}

Die FindAssociation-Methode, aufgerufen von EnumerateAssociatedPrinters, überprüft, ob ein Drucker der aktuellen Anwendung zugeordnet ist. Mit anderen Worten: Diese Methode überprüft, ob es sich bei der App um eine UWP-Geräte-App handelt. Diese Zuordnung ist vorhanden, wenn die App und der Drucker in Gerätemetadaten auf dem lokalen PC definiert sind.

Dieses Beispiel zeigt die FindAssociation-Methode aus der Datei InkLevel.xaml.cs :

async void FindAssociation(DeviceInformation deviceInfo, string containerId)
{

    // Specifically telling CreateFromIdAsync to retrieve the AppPackageFamilyName. 
    string packageFamilyName = "System.Devices.AppPackageFamilyName";
    string[] containerPropertiesToGet = new string[] { packageFamilyName };

    // CreateFromIdAsync needs braces on the containerId string.
    string containerIdwithBraces = "{" + containerId + "}";

    // Asynchronously getting the container information of the printer.
    PnpObject containerInfo = await PnpObject.CreateFromIdAsync(PnpObjectType.DeviceContainer, containerIdwithBraces, containerPropertiesToGet);

    // Printers could be associated with other device apps, only the ones with package family name
    // matching this app's is associated with this app. The packageFamilyName for this app will be found in this app's packagemanifest
    string appPackageFamilyName = "Microsoft.SDKSamples.DeviceAppForPrinters.CS_8wekyb3d8bbwe";
    var prop = containerInfo.Properties;

    // If the packageFamilyName of the printer container matches the one for this app, the printer is associated with this app.
    string[] packageFamilyNameList = (string[])prop[packageFamilyName];
    if (packageFamilyNameList != null)
    {
        for (int j = 0; j < packageFamilyNameList.Length; j++)
        {
            if (packageFamilyNameList[j].Equals(appPackageFamilyName))
            {
                AddToList(deviceInfo);
            }
        }
    }
}

Wenn eine Zuordnung gefunden wird, verwendet die FindAssociation-Methode die AddToList-Methode, um die Geräte-ID einer Liste der zugeordneten Geräte-IDs hinzuzufügen. Diese IDs werden in einem ComboBox-Steuerelement mit dem Namen AssociatedPrintersgespeichert.

Dieses Beispiel zeigt die AddToList-Methode aus der Datei InkLevel.xaml.cs:

void AddToList(DeviceInformation deviceInfo)
{
    // Creating a new display item so the user sees the friendly name instead of the interfaceId.
    ComboBoxItem item = new ComboBoxItem();
    item.Content = deviceInfo.Properties["System.ItemNameDisplay"] as string;
    item.DataContext = deviceInfo.Id;
    AssociatedPrinters.Items.Add(item);

    // If this is the first printer to be added to the combo box, select it.
    if (AssociatedPrinters.Items.Count == 1)
    {
        AssociatedPrinters.SelectedIndex = 0;
    }
}

Schritt 2: Anzeigen des Status

Die GetInkStatus Methode verwendet ein asynchrones ereignisbasiertes Muster, um Informationen vom Drucker anzufordern. Diese Methode verwendet eine zugeordnete Geräte-ID, um einen Gerätekontext abzurufen, der zum Abrufen des Gerätestatus verwendet werden kann. Der Aufruf der printHelper.SendInkLevelQuery() Methode initiiert die Geräteabfrage. Wenn die Antwort zurückgegeben wird, wird die OnInkLevelReceived Methode aufgerufen, und die Benutzeroberfläche wird aktualisiert.

Hinweis

Dieses C#-Beispiel folgt einem anderen Muster als das JavaScript-Beispiel, da Sie mit C# einen Dispatcher an die PrintHelperClass senden können, damit diese die Ereignismeldungen zurück an den UI-Thread senden kann.

Dieses Beispiel zeigt die Methoden GetInkStatus und OnInkLevelReceived aus der Datei InkLevel.xaml.cs:

void GetInkStatus(object sender, RoutedEventArgs e)
{
    if (AssociatedPrinters.Items.Count > 0)
    {
        // Get the printer that the user has selected to query.
        ComboBoxItem selectedItem = AssociatedPrinters.SelectedItem as ComboBoxItem;

        // The interfaceId is retrieved from the detail field.
        string interfaceId = selectedItem.DataContext as string;

        try
        {
            // Unsubscribe existing ink level event handler, if any.
            if (printHelper != null)
            {
                printHelper.OnInkLevelReceived -= OnInkLevelReceived;
                printHelper = null;
            }

            object context = Windows.Devices.Printers.Extensions.PrintExtensionContext.FromDeviceId(interfaceId);printHelper.SendInkLevelQuery()

            // Use the PrinterHelperClass to retrieve the bidi data and display it.
            printHelper = new PrintHelperClass(context);
            try
            {
                printHelper.OnInkLevelReceived += OnInkLevelReceived;
                printHelper.SendInkLevelQuery();

                rootPage.NotifyUser("Ink level query successful", NotifyType.StatusMessage);
            }
            catch (Exception)
            {
                rootPage.NotifyUser("Ink level query unsuccessful", NotifyType.ErrorMessage);
            }
        }
        catch (Exception)
        {
            rootPage.NotifyUser("Error retrieving PrinterExtensionContext from InterfaceId", NotifyType.ErrorMessage);
        }
    }
}

private void OnInkLevelReceived(object sender, string response)
{
    BidiOutput.Text = response;
}

Die Druckhelferklasse kümmert sich um das Senden der Bidi-Abfrage an das Gerät und den Empfang der Antwort.

Dieses Beispiel zeigt die SendInkLevelQuery Methode und andere aus der PrintHelperClass.cs Datei. Beachten Sie, dass hier nur einige der Druckhilfsklassenmethoden angezeigt werden. Laden Sie das Beispiel für Druckeinstellungen und Druckbenachrichtigungen herunter, um den vollständigen Code anzuzeigen.

public void SendInkLevelQuery()
{
    printerQueue.OnBidiResponseReceived += OnBidiResponseReceived;

    // Send the query.
    string queryString = "\\Printer.Consumables";
    printerQueue.SendBidiQuery(queryString);
}

private void OnBidiResponseReceived(object sender, PrinterQueueEventArgs responseArguments)
{
    // Invoke the ink level event with appropriate data.
    dispatcher.RunAsync(
        Windows.UI.Core.CoreDispatcherPriority.Normal,
        () =>
        {
            OnInkLevelReceived(sender, ParseResponse(responseArguments));
        });
}

private string ParseResponse(PrinterQueueEventArgs responseArguments)
{
    if (responseArguments.StatusHResult == (int)HRESULT.S_OK)
        return responseArguments.Response;
    else
        return InvalidHResult(responseArguments.StatusHResult);
}

private string InvalidHResult(int result)
{
    switch (result)
    {
        case unchecked((int)HRESULT.E_INVALIDARG):
            return "Invalid Arguments";
        case unchecked((int)HRESULT.E_OUTOFMEMORY):
            return "Out of Memory";
        case unchecked((int)HRESULT.ERROR_NOT_FOUND):
            return "Not found";
        case (int)HRESULT.S_FALSE:
            return "False";
        case (int)HRESULT.S_PT_NO_CONFLICT:
            return "PT No Conflict";
        default:
            return "Undefined status: 0x" + result.ToString("X");
    }
}

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 Gerätemetadaten-Erstellungsassistenten feststellen, wie im Thema Schritt 2 beschrieben: Erstellen von Gerätemetadaten für Ihre UWP-Geräte-App beschrieben.

Hinweis

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.

    Hinweis

    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.

Problembehandlung

Problem: Drucker beim Aufzählen von Geräten, die der App zugeordnet sind, können nicht gefunden werden

Wenn Ihr Drucker beim Aufzählen der zugehörigen Drucker nicht gefunden wird:

  • Mögliche Ursache: Die Testsignatur ist nicht aktiviert. Informationen zum Aktivieren finden Sie im Abschnitt Debuggen in diesem Thema.

  • Mögliche Ursache: Die App fragt nicht nach dem richtigen Paketfamiliennamen ab. Überprüfen Sie den Paketfamiliennamen in Ihrem Code. Öffnen Sie package.appxmanifest in Microsoft Visual Studio und stellen Sie sicher, dass der Name der Paketfamilie, den Sie abfragen, mit dem Namen auf der Registerkarte Packaging im Feld Name der Paketfamilie übereinstimmt.

  • Mögliche Ursache: Die Gerätemetadaten sind nicht mit dem Paketfamiliennamen verknüpft. Verwenden Sie den Assistenten zum Erstellen von Gerätemetadaten, um die Gerätemetadaten zu öffnen und den Paketfamiliennamen zu überprüfen. Starten Sie den Assistenten von %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, indem Sie auf DeviceMetadataWizard.exe doppelklicken.

Problem: Der der App zugeordnete Drucker wurde gefunden, kann aber keine Bidi-Informationen abfragen.

Wenn ihr Drucker beim Aufzählen der zugeordneten Drucker gefunden wurde, aber eine Bidi-Abfrage einen Fehler zurückgibt...

  • Mögliche Ursache: Falscher Paketfamilienname. Überprüfen Sie den Paketfamiliennamen in Ihrem Code. Öffnen Sie package.appxmanifest in Visual Studio und stellen Sie sicher, dass der Name der Paketfamilie, den Sie abfragen, mit dem Namen auf der Registerkarte Packaging im Feld Name der Paketfamilie übereinstimmt.

  • Mögliche Ursache: Drucker wurde mit einem v3-Drucker anstelle eines v4-Druckers installiert. Um zu sehen, welche Version installiert ist, öffnen Sie PowerShell, und geben Sie den folgenden Befehl ein:

    get-printer | Select Name, {(get-printerdriver -Name $_.DriverName).MajorVersion}
    

Entwickeln von v4-Drucktreibern

Druckererweiterungsschnittstellen (v4 Drucktreiber)

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)