Partager via


Récupération des méthodes de service prises en charge

Les méthodes de service encapsulent des fonctionnalités que chaque service définit et implémente. Elles sont spécifiques à chaque type de service et sont représentées par un GUID unique.

Par exemple, le service Contacts définit une méthode BeginSync que les applications appellent pour préparer l’appareil à la synchronisation des objets Contact, et une méthode EndSync pour informer l’appareil que la synchronisation est terminée.

Les applications peuvent interroger par programmation les méthodes prises en charge et accéder à ces méthodes et à leurs attributs à l’aide de l’interface IPortableDeviceServiceCapabilities .

Les méthodes de service ne doivent pas être confondues avec les commandes WPD. Les commandes WPD font partie de l’interface de pilote de périphérique WPD standard et constituent le mécanisme de communication entre une application WPD et le pilote. Les commandes sont prédéfinies, regroupées par catégories, par exemple, WPD_CATEGORY_COMMON et sont représentées par une structure PROPERTYKEY. Pour plus d’informations, consultez la rubrique Commandes .

L’application WpdServicesApiSample inclut du code qui montre comment une application peut récupérer les méthodes prises en charge par un service Contacts donné à l’aide des interfaces du tableau suivant.

Interface Description
IPortableDeviceService Permet de récupérer l’interface IPortableDeviceServiceCapabilities pour accéder aux méthodes de service prises en charge.
IPortableDeviceServiceCapabilities Fournit l’accès aux méthodes, attributs de méthode et paramètres de méthode pris en charge.
IPortableDevicePropVariantCollection Contient la liste des méthodes prises en charge.
IPortableDeviceValues Contient les attributs d’une méthode et des paramètres d’une méthode donnée.
IPortableDeviceKeyCollection Contient les paramètres d’une méthode donnée.

 

Lorsque l’utilisateur choisit l’option « 5 » sur la ligne de commande, l’application appelle la méthode ListSupportedMethods qui se trouve dans le module ServiceMethods.cpp.

Notez qu’avant de récupérer la liste des événements, l’exemple d’application ouvre un service Contacts sur un appareil connecté.

Dans WPD, une méthode est décrite par son nom, ses droits d’accès, ses paramètres et ses données associées. L’exemple d’application affiche un nom convivial, par exemple, « CustomMethod » ou un GUID. Le nom ou GUID de la méthode est suivi des données d’accès (« Lecture/écriture »), du nom de tout format associé et des données de paramètre. Ces données incluent le nom du paramètre, l’utilisation, VARTYPE et le formulaire.

Cinq méthodes du module ServiceMethods.cpp prennent en charge la récupération des méthodes (et des données associées) pour le service Contacts donné : ListSupportedMethods, DisplayMethod, DisplayMethodAccess, DisplayFormat et DisplayMethodParameters. La méthode ListSupportedMethods récupère le nombre de méthodes prises en charge et l’identificateur GUID pour chacune d’elles ; elle appelle ensuite la méthode DisplayMethod . La méthode DisplayMethod appelle la méthode IPortableDeviceServiceCapapbilities::GetMethodAttributes pour récupérer les options, paramètres, etc. de la méthode donnée. Une fois que DisplayMethod a récupéré les données de la méthode, il restitue le nom (ou GUID), les restrictions d’accès, le format associé (le cas échéant) et les descriptions des paramètres. DisplayMethodAccess, DisplayFormat et DisplayMethodParameters sont des fonctions d’assistance qui restituent leurs champs de données respectifs.

La méthode ListSupportedMethods appelle la méthode IPortableDeviceService::Capabilities pour récupérer une interface IPortableDeviceServiceCapabilities . À l’aide de cette interface, il récupère les méthodes prises en charge en appelant la méthode IPortableDeviceServiceCapabilities::GetSupportedMethods . La méthode GetSupportedMethods récupère les GUID de chaque méthode prise en charge par le service et copie ce GUID dans un objet IPortableDevicePropVariantCollection .

Le code suivant utilise la méthode ListSupportedMethods .

// List all supported methods on the service
void ListSupportedMethods(IPortableDeviceService* pService)
{
    HRESULT hr              = S_OK;
    DWORD   dwNumMethods    = 0;
    CComPtr<IPortableDeviceServiceCapabilities>     pCapabilities;
    CComPtr<IPortableDevicePropVariantCollection>   pMethods;

    if (pService == NULL)
    {
        printf("! A NULL IPortableDeviceService interface pointer was received\n");
        return;
    }

    // Get an IPortableDeviceServiceCapabilities interface from the IPortableDeviceService interface to
    // access the service capabilities-specific methods.
    hr = pService->Capabilities(&pCapabilities);
    if (FAILED(hr))
    {
        printf("! Failed to get IPortableDeviceServiceCapabilities from IPortableDeviceService, hr = 0x%lx\n",hr);
    }

    // Get all methods supported by the service.
    if (SUCCEEDED(hr))
    {
        hr = pCapabilities->GetSupportedMethods(&pMethods);
        if (FAILED(hr))
        {
            printf("! Failed to get supported methods from the service, hr = 0x%lx\n",hr);
        }
    }

    // Get the number of supported methods found on the service.
    if (SUCCEEDED(hr))
    {
        hr = pMethods->GetCount(&dwNumMethods);
        if (FAILED(hr))
        {
            printf("! Failed to get number of supported methods, hr = 0x%lx\n",hr);
        }
    }

    printf("\n%d Supported Methods Found on the service\n\n", dwNumMethods);

    // Loop through each method and display it
    if (SUCCEEDED(hr))
    {
        for (DWORD dwIndex = 0; dwIndex < dwNumMethods; dwIndex++)
        {
            PROPVARIANT pv = {0};
            PropVariantInit(&pv);
            hr = pMethods->GetAt(dwIndex, &pv);

            if (SUCCEEDED(hr))
            {
                // We have a method.  It is assumed that
                // methods are returned as VT_CLSID VarTypes.
                if (pv.puuid != NULL)
                {
                    DisplayMethod(pCapabilities, *pv.puuid);
                    printf("\n");
                }
            }

            PropVariantClear(&pv);
        }
    }    
}

Une fois que la méthode ListSupportedMethods a récupéré le GUID pour chaque événement pris en charge par le service donné, elle appelle la méthode DisplayMethod pour récupérer les attributs spécifiques à la méthode. Ces attributs incluent : le nom de script de la méthode, les restrictions d’accès requises, tout format associé et la liste des paramètres.

La méthode DisplayMethod appelle la méthode IPortableDeviceServiceCapabilities::GetMethodAttributes pour récupérer une collection d’attributs pour la méthode donnée. Il appelle ensuite la méthode IPortableDeviceValues::GetStringValue pour récupérer le nom de la méthode. DisplayMethod appelle IPortableDeviceValues::GetUnsignedIntegerValue pour récupérer les restrctions d’accès. Après cela, il appelle IPortableDeviceValues::GetGuidValue pour récupérer n’importe quel format associé. Enfin, displayMethod appelle IPortableDeviceValues::GetIPortableDeviceKeyCollectionValue pour récupérer les données de paramètre. Il transmet les données retournées par ces méthodes aux fonctions d’assistance DisplayMethodAccess, DisplayFormat et DisplayMethodParameters , qui restituent les informations pour la méthode donnée.

Le code suivant utilise la méthode DisplayMethod .

// Display basic information about a method
void DisplayMethod(
    IPortableDeviceServiceCapabilities* pCapabilities,
    REFGUID                             Method)
{
    CComPtr<IPortableDeviceValues> pAttributes;

    // Get the method attributes which describe the method
    HRESULT hr = pCapabilities->GetMethodAttributes(Method, &pAttributes);
    if (FAILED(hr))
    {
        printf("! Failed to get the method attributes, hr = 0x%lx\n",hr);
    }

    if (SUCCEEDED(hr))
    {
        PWSTR   pszMethodName  = NULL;
        DWORD   dwMethodAccess = WPD_COMMAND_ACCESS_READ;
        GUID    guidFormat     = GUID_NULL;

        CComPtr<IPortableDeviceValues>          pOptions;
        CComPtr<IPortableDeviceKeyCollection>   pParameters;

        // Display the name of the method if available. Otherwise, fall back to displaying the GUID.
        hr = pAttributes->GetStringValue(WPD_METHOD_ATTRIBUTE_NAME, &pszMethodName);
        if (SUCCEEDED(hr))
        {
            printf("%ws", pszMethodName);
        }
        else
        {
            printf("%ws", (PWSTR)CGuidToString(Method));
        }       

        // Display the method access if available, otherwise default to WPD_COMMAND_ACCESS_READ access
        hr = pAttributes->GetUnsignedIntegerValue(WPD_METHOD_ATTRIBUTE_ACCESS, &dwMethodAccess);
        if (FAILED(hr))
        {
            dwMethodAccess = WPD_COMMAND_ACCESS_READ;
            hr = S_OK;
        }
        printf("\n\tAccess: ");
        DisplayMethodAccess(dwMethodAccess);

        // Display the associated format if specified.
        // Methods that have an associated format may only be supported for that format.
        // Methods that don't have associated formats generally apply to the entire service.
        hr = pAttributes->GetGuidValue(WPD_METHOD_ATTRIBUTE_ASSOCIATED_FORMAT, &guidFormat);
        if (SUCCEEDED(hr))
        {
            printf("\n\tAssociated Format: ");
            DisplayFormat(pCapabilities, guidFormat);
        }

        // Display the method parameters, if available
        hr = pAttributes->GetIPortableDeviceKeyCollectionValue(WPD_METHOD_ATTRIBUTE_PARAMETERS, &pParameters);
        if (SUCCEEDED(hr))
        {
            DisplayMethodParameters(pCapabilities, Method, pParameters);
        }
        
        CoTaskMemFree(pszMethodName);
        pszMethodName = NULL;

    }
}

La fonction d’assistance DisplayMethodAccess reçoit une valeur DWORD qui contient les options d’accès de la méthode. Il compare cette valeur à WPD_COMMAND_ACCESS_READ et WPD_COMMAND_ACCESS_READWRITE pour déterminer le privilège d’accès de la méthode. À l’aide du résultat, il affiche une chaîne indiquant la restriction d’accès pour la méthode donnée.

Le code suivant utilise la fonction d’assistance DisplayMethodAccess .

void DisplayMethodAccess(
    DWORD   dwAccess)
{
    switch(static_cast<WPD_COMMAND_ACCESS_TYPES>(dwAccess))
    {
        case WPD_COMMAND_ACCESS_READ:
            printf("Read");
            break;
            
        case WPD_COMMAND_ACCESS_READWRITE:
            printf("Read/Write");
            break;

        default:
            printf("Unknown Access");
            break;
    }
}

La fonction d’assistance DisplayMethod reçoit un objet IPortableDeviceServiceCapabilities et le GUID de la méthode en tant que paramètres. À l’aide de l’objet IPortableDeviceServiceCapabilities , il appelle la méthode IPortableDeviceServiceCapabilities::GetMethodAttributes pour récupérer les attributs de la méthode et les afficher dans la fenêtre de console de l’application.

La fonction d’assistance DisplayMethodParameters reçoit un objet IPortableDeviceServiceCapabilities , le GUID de la méthode et un objet IPortableDeviceKeyCollection contenant les paramètres de la méthode. À l’aide de l’objet IPortableDeviceKeyCollection , il appelle la méthode IPortableDeviceServiceCapabilities::GetMethodParameterAttributes pour récupérer le nom, l’utilisation, le VARTYPE et le formulaire du paramètre. Il restitue ces informations dans la fenêtre de console de l’application.

Le code suivant utilise la fonction d’assistance DisplayMethodParameters .

// Display the method parameters.
void DisplayMethodParameters(
    IPortableDeviceServiceCapabilities* pCapabilities,
    REFGUID                             Method,
    IPortableDeviceKeyCollection*       pParameters)
{
    DWORD   dwNumParameters = 0;

    // Get the number of parameters for this event.
    HRESULT hr = pParameters->GetCount(&dwNumParameters);
    if (FAILED(hr))
    {
        printf("! Failed to get number of parameters, hr = 0x%lx\n",hr);
    }

    printf("\n\t%d Method Parameters:\n", dwNumParameters);

    // Loop through each parameter and display it
    if (SUCCEEDED(hr))
    {
        for (DWORD dwIndex = 0; dwIndex < dwNumParameters; dwIndex++)
        {
            PROPERTYKEY parameter;
            hr = pParameters->GetAt(dwIndex, &parameter);

            if (SUCCEEDED(hr))
            {
                CComPtr<IPortableDeviceValues> pAttributes;

                // Display the parameter's Name, Usage, Vartype, and Form
                hr = pCapabilities->GetMethodParameterAttributes(Method, parameter, &pAttributes);
                if (FAILED(hr))
                {
                    printf("! Failed to get the method parameter attributes, hr = 0x%lx\n",hr);
                }

                if (SUCCEEDED(hr))
                {
                    PWSTR   pszParameterName    = NULL;
                    DWORD   dwAttributeVarType  = 0;
                    DWORD   dwAttributeForm     = WPD_PARAMETER_ATTRIBUTE_FORM_UNSPECIFIED;
                    DWORD   dwAttributeUsage    = (DWORD)-1;

                    hr = pAttributes->GetStringValue(WPD_PARAMETER_ATTRIBUTE_NAME, &pszParameterName);
                    if (SUCCEEDED(hr))
                    {
                        printf("\t\tName: %ws\n", pszParameterName);
                    }
                    else
                    {
                        printf("! Failed to get the method parameter name, hr = 0x%lx\n",hr);
                    }

                    // Read the WPD_PARAMETER_ATTRIBUTE_USAGE value, if specified. 
                    hr = pAttributes->GetUnsignedIntegerValue(WPD_PARAMETER_ATTRIBUTE_USAGE, &dwAttributeUsage);
                    if (SUCCEEDED(hr))
                    {
                        printf("\t\tUsage: ");
                        DisplayParameterUsage(dwAttributeUsage);
                        printf("\n");
                    }
                    else
                    {
                        printf("! Failed to get the method parameter usage, hr = 0x%lx\n",hr);
                    }

                    hr = pAttributes->GetUnsignedIntegerValue(WPD_PARAMETER_ATTRIBUTE_VARTYPE, &dwAttributeVarType);
                    if (SUCCEEDED(hr))
                    {
                        printf("\t\tVARTYPE: ");
                        DisplayVarType(static_cast<VARTYPE>(dwAttributeVarType));
                        printf("\n");
                    }
                    else
                    {
                        printf("! Failed to get the method parameter VARTYPE, hr = 0x%lx\n",hr);
                    }

                    // Read the WPD_PARAMETER_ATTRIBUTE_FORM value.
                    hr = pAttributes->GetUnsignedIntegerValue(WPD_PARAMETER_ATTRIBUTE_FORM, &dwAttributeForm);
                    if (FAILED(hr))
                    {
                        // If the read fails, assume WPD_PARAMETER_ATTRIBUTE_FORM_UNSPECIFIED
                        dwAttributeForm = WPD_PARAMETER_ATTRIBUTE_FORM_UNSPECIFIED;
                        hr = S_OK;
                    }

                    printf("\t\tForm: ");
                    DisplayParameterForm(dwAttributeForm);
                    printf("\n");

                    CoTaskMemFree(pszParameterName);
                    pszParameterName = NULL;
                }
                
                printf("\n");
            }
        }
    }
}

IPortableDeviceKeyCollection

IPortableDeviceService

IPortableDeviceServiceCapabilities

IPortableDeviceValues

WpdServicesApiSample