Comment afficher l’état de l’imprimante dans une application UWP pour périphérique

Dans Windows 8.1, les utilisateurs peuvent consulter l’état de leur imprimante à partir de l’interface utilisateur moderne d’une application d’appareil UWP. Cette rubrique se base sur la version C# de l’exemple des paramètres d’impression et des notifications d’impression pour démontrer comment interroger l’état de l’imprimante et l’afficher. Pour en savoir plus sur les applications d’appareils UWP en général, veuillez consulter la rubrique Découverte des applications d’appareils UWP.

La version C# de l’exemple des paramètres d’impression et de notifications d’impression utilise la page InkLevel.xaml pour montrer comment obtenir l’état de l’imprimante (dans ce cas, le niveau d’encre) et l’afficher. Une classe d’assistance d’impression est utilisée pour créer un contexte de périphérique (IPrinterExtensionContext) et effectuer les requêtes de périphérique. Le fichier PrinterHelperClass.cs se trouve dans le projet DeviceAppForPrintersLibrary et utilise des API définies dans le projet PrinterExtensionLibrary. La bibliothèque d’extension d’imprimante offre un moyen pratique d’accéder aux interfaces d’extension d’imprimante du pilote d’impression v4. Pour plus d’informations, veuillez consulter l’aperçu de la bibliothèque d’extension d’imprimante.

Remarque

Les exemples de code présentés dans ce sujet sont basés sur la version C# de l’exemple Paramètres d’impression et notifications d’impression. Cet exemple est également disponible en JavaScript et C++. Notez que comme C++ peut accéder directement à COM, la version C++ de l’exemple n’inclut pas de projets de bibliothèque de code. Téléchargez les exemples pour voir les dernières versions du code.

Prérequis

Avant de commencer :

  1. Assurez-vous que votre imprimante est installée avec un pilote d’impression v4. Pour plus d’informations, veuillez consulter la section Développement de pilotes d’impression v4.

  2. Préparez votre PC de développement. Veuillez consulter la section Bien démarrer pour obtenir des informations sur le téléchargement des outils et la création d’un compte développeur.

  3. Associez votre application au magasin. Consultez Étape 1 : Créer une application UWP pour périphérique pour plus d’informations à ce sujet.

  4. Créez des métadonnées de périphérique pour votre imprimante qui l’associent à votre application. Consultez Créer des métadonnées de périphérique pour en savoir plus à ce sujet.

  5. Si vous écrivez votre application en C# ou JavaScript, ajoutez les projets PrinterExtensionLibrary et DeviceAppForPrintersLibrary à la solution de votre application UWP pour périphérique. Vous pouvez trouver chacun de ces projets dans l’exemple Paramètres d’impression et notifications d’impression.

    Remarque

    Comme C++ peut accéder directement à COM, les applications C++ n’ont pas besoin d’une bibliothèque séparée pour travailler avec le contexte de périphérique d’imprimante basé sur COM.

Étape 1 : Trouver l’imprimante

Avant de pouvoir créer un contexte de périphérique, l’application doit déterminer l’ID de périphérique de l’imprimante. Pour cela, l’exemple utilise la méthode EnumerateAssociatedPrinters pour rechercher toutes les imprimantes connectées au PC. Ensuite, il vérifie le conteneur de chaque imprimante et cherche une association en comparant la propriété PackageFamilyName de chaque conteneur.

Remarque

Le System.Devices.AppPackageFamilyName pour les périphériques associés à votre application peut être trouvé sous l’onglet Packaging dans le concepteur de manifeste de Microsoft Visual Studio.

Cet exemple montre la méthode EnumerateAssociatedPrinters du fichier 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());
    }
}

La méthode FindAssociation, appelée par EnumerateAssociatedPrinters, vérifie si une imprimante est associée à l’application courante. En d’autres termes, cette méthode vérifie si l’application est une application UWP pour périphérique. Cette association existe lorsque l’application et l’imprimante sont définies dans les métadonnées de périphérique sur le PC local.

Cet exemple montre la méthode FindAssociation du fichier 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);
            }
        }
    }
}

Lorsqu’une association est trouvée, la méthode FindAssociation utilise la méthode AddToList pour ajouter l’ID de périphérique à une liste d’ID de périphériques associés. Ces ID sont stockés dans une ComboBox nommée AssociatedPrinters.

Cet exemple montre la méthode AddToList du fichier 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;
    }
}

Étape 2 : Afficher l’état

La méthode GetInkStatus utilise un modèle événementiel asynchrone pour demander des informations à l’imprimante. Cette méthode utilise un ID de périphérique associé pour obtenir un contexte de périphérique qui peut être utilisé pour obtenir le statut du périphérique. L’appel à la méthode printHelper.SendInkLevelQuery() initie la requête de périphérique. Lorsque la réponse revient, la méthode OnInkLevelReceived est appelée et l’interface utilisateur est mise à jour.

Remarque

Cet exemple en C# suit un modèle différent de l’exemple en JavaScript, car C# vous permet d’envoyer un dispatcher à la classe PrintHelperClass pour qu’elle puisse poster les messages d’événement sur le fil d’interface utilisateur.

Cet exemple montre les méthodes GetInkStatus et OnInkLevelReceived du fichier 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;
}

La classe d’assistance d’impression se charge d’envoyer la requête Bidi au périphérique et de recevoir la réponse.

Cet exemple montre la méthode SendInkLevelQuery, et d’autres, du fichier PrintHelperClass.cs. Notez que seules certaines des méthodes de la classe d’assistance d’impression sont présentées ici. Téléchargez l’exemple Paramètres d’impression et notifications d’impression pour voir le code complet.

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

Test

Avant de pouvoir tester votre application UWP pour périphérique, elle doit être liée à votre imprimante à l’aide de métadonnées de périphérique.

Vous avez besoin d’une copie du package de métadonnées de périphérique pour votre imprimante, pour y ajouter les informations de l’application de périphérique. Si vous n’avez pas de métadonnées de périphérique, vous pouvez les construire en utilisant l’Assistant de création de métadonnées de périphérique comme décrit dans le sujet Étape 2 : Créer des métadonnées de périphérique pour votre application UWP pour périphérique.

Remarque

Pour utiliser l’Assistant de création de métadonnées de périphérique, vous devez installer Microsoft Visual Studio Professional, Microsoft Visual Studio Ultimate, ou le SDK autonome pour Windows 8.1, avant de compléter la procédure de cette rubrique. L’installation de Microsoft Visual Studio Express pour Windows installe une version du SDK qui n’inclut pas l’assistant.

Les étapes suivantes construisent votre application et installent les métadonnées de périphérique.

  1. Activez la signature de test.

    1. Lancez l’Assistant de création de métadonnées de périphérique depuis %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, en double-cliquant sur DeviceMetadataWizard.exe

    2. Depuis le menu Outils, sélectionnez Activer la signature de test.

  2. Redémarrez l’ordinateur

  3. Construisez la solution en ouvrant le fichier de solution (.sln). Appuyez sur F7 ou allez dans Construire->Construire la solution depuis le menu supérieur après que l’exemple ait été chargé.

  4. Déconnectez et désinstallez l’imprimante. Cette étape est nécessaire pour que Windows lise les métadonnées de périphérique mises à jour la prochaine fois que le périphérique est détecté.

  5. Éditez et sauvegardez les métadonnées de périphérique. Pour lier l’application de périphérique à votre périphérique, vous devez associer l’application de périphérique à votre périphérique.

    Remarque

    Si vous n’avez pas encore créé vos métadonnées de périphérique, consultez Étape 2 : Créer des métadonnées de périphérique pour votre application UWP pour périphérique.

    1. Si l’Assistant de création de métadonnées de périphérique n’est pas encore ouvert, lancez-le depuis %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, en double-cliquant sur DeviceMetadataWizard.exe.

    2. Cliquez sur Éditer les métadonnées de périphérique. Cela vous permettra d’éditer votre package de métadonnées de périphérique existant.

    3. Dans la boîte de dialogue Ouvrir, localisez le package de métadonnées de périphérique associé à votre application UWP pour périphérique. (Il a une extension de fichier devicemetadata-ms).

    4. Sur la page Spécifier les informations de l’application UWP pour périphérique, saisissez les informations de l’application Microsoft Store dans la boîte Application UWP pour périphérique. Cliquez sur Importer le fichier manifeste de l’application UWP pour entrer automatiquement le Nom du package, le Nom de l’éditeur, et l’ID de l’application UWP.

    5. Si votre application s’inscrit pour des notifications d’imprimante, remplissez la boîte Gestionnaires de notifications. Dans ID de l’événement, saisissez le nom du gestionnaire d’événements d’impression. Dans Actif de l’événement, saisissez le nom du fichier où ce code réside.

    6. Lorsque vous avez terminé, cliquez sur Suivant jusqu’à ce que vous arriviez à la page Terminer.

    7. Sur la page Revoir le package de métadonnées de périphérique, assurez-vous que tous les paramètres sont corrects et sélectionnez la case à cocher Copier le package de métadonnées de périphérique dans le magasin de métadonnées sur l’ordinateur local. Ensuite, cliquez sur Enregistrer.

  6. Reconnectez votre imprimante pour que Windows lise les métadonnées de périphérique mises à jour lorsque le périphérique est connecté.

Dépannage

Problème : Impossible de trouver l’imprimante lors de l’énumération des périphériques associés à l’application

Si votre imprimante n’est pas trouvée lors de l’énumération des imprimantes associées :

  • Cause possible : Le test de signature n’est pas activé. Consultez la section Débogage de ce sujet pour savoir comment l’activer.

  • Cause possible : L’application ne recherche pas le bon nom de famille de package. Vérifiez le nom de famille de package dans votre code. Ouvrez package.appxmanifest dans Microsoft Visual Studio et assurez-vous que le nom de famille de package que vous recherchez correspond à celui de l’onglet Packaging, dans le champ Nom de famille de package.

  • Cause possible : Les métadonnées de périphérique ne sont pas associées au nom de famille de package. Utilisez l’Assistant de création de métadonnées de périphérique pour ouvrir les métadonnées de périphérique et vérifier le nom de famille de package. Lancez l’assistant depuis %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, en double-cliquant sur DeviceMetadataWizard.exe.

Problème : Imprimante associée à l’application trouvée, mais impossible de requérir les infos Bidi

Si votre imprimante a été trouvée lors de l’énumération des imprimantes associées, mais qu’une requête Bidi renvoie une erreur...

  • Cause possible : Nom de famille de package incorrect. Vérifiez le nom de famille de package dans votre code. Ouvrez package.appxmanifest dans Visual Studio et assurez-vous que le nom de famille de package que vous recherchez correspond à celui de l’onglet Packaging, dans le champ Nom de famille de package.

  • Cause possible : L’imprimante a été installée en utilisant une imprimante v3, plutôt qu’une imprimante v4. Pour voir quelle version est installée, ouvrez PowerShell et saisissez la commande suivante :

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

Développement de pilotes d’impression v4

Interfaces d’extension d’imprimante (pilote d’impression v4)

Communications bidirectionnelles

Bien démarrer avec les applications UWP

Créer une application UWP pour périphérique (guide pas à pas)

Créer des métadonnées de périphérique pour une application UWP pour périphérique (guide étape par étape)