Share via


Auflisten von Dienstinhalten

Nachdem Ihre Anwendung einen Dienst geöffnet hat, kann sie mit der Ausführung dienstbezogener Vorgänge beginnen. Im Fall der WpdServicesApiSample-Anwendung ist einer dieser Vorgänge die Enumeration von Inhalten für einen bestimmten Contacts-Dienst. In der folgenden Tabelle werden die verwendeten Schnittstellen beschrieben.

Schnittstelle Beschreibung
IPortableDeviceService Wird verwendet, um die IPortableDeviceContent2-Schnittstelle für den Zugriff auf Inhalte im Dienst abzurufen.
IPortableDeviceContent2 Wird verwendet, um die IEnumPortableDeviceObjectIDs-Schnittstelle abzurufen, um Objekte im Dienst aufzulisten.
IEnumPortableDeviceObjectIDs Wird verwendet, um Objekte im Dienst aufzulisten.

 

Der Code der Inhaltsenumeration befindet sich im Modul ContentEnumeration.cpp. Dieser Code befindet sich in den Methoden EnumerateAllContent und RecursiveEnumerate . Die erste Methode ruft letzteres auf.

Die EnumerateContent-Methode verwendet einen Zeiger auf ein IPortableDeviceService-Objekt als einen Parameter. Dieses Objekt entspricht einem Dienst, den die Anwendung zuvor geöffnet hat, als sie die IPortableDeviceService::Open-Methode aufgerufen hat .

Die EnumerateContent-Methode erstellt ein IPortableDeviceContent2-Objekt und übergibt dieses Objekt an die IPortableDeviceService::Content-Methode . Diese Methode wiederum ruft den Inhalt auf der Stammebene des Diensts ab und beginnt dann rekursiv mit dem Abrufen von Inhalten, die unter dem Stamm gefunden wurden.

Der folgende Code entspricht der EnumerateContent-Methode .

// Enumerate all content on the service starting with the
// "DEVICE" object
void EnumerateAllContent(
    IPortableDeviceService* pService)
{
    HRESULT                          hr = S_OK;
    CComPtr<IPortableDeviceContent2> pContent;

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

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

    // Enumerate content starting from the "DEVICE" object.
    if (SUCCEEDED(hr))
    {
        printf("\n");
        RecursiveEnumerate(WPD_DEVICE_OBJECT_ID, pContent);
    }
}

Der folgende Code entspricht der RecursiveEnumerate-Methode . Die RecursiveEnumerate-Methode instanziiert eine IEnumPortableDeviceObjectIDs-Schnittstelle für das angegebene übergeordnete Objekt und ruft IEnumPortableDeviceObjectIDs::Next auf, wobei ein Batch von unmittelbar untergeordneten Objekten abgerufen wird. Für jedes untergeordnete Objekt wird RecursiveEnumerate erneut aufgerufen, um seine untergeordneten Objekte zurückzugeben usw.

// Recursively called function which enumerates using the specified
// object identifier as the parent.
void RecursiveEnumerate(
    PCWSTR                   pszObjectID,
    IPortableDeviceContent2* pContent)
{
    CComPtr<IEnumPortableDeviceObjectIDs> pEnumObjectIDs;

    // Print the object identifier being used as the parent during enumeration.
    printf("%ws\n",pszObjectID);

    // Get an IEnumPortableDeviceObjectIDs interface by calling EnumObjects with the
    // specified parent object identifier.
    HRESULT hr = pContent->EnumObjects(0,               // Flags are unused
                                       pszObjectID,     // Starting from the passed in object
                                       NULL,            // Filter is unused
                                       &pEnumObjectIDs);
    if (FAILED(hr))
    {
        printf("! Failed to get IEnumPortableDeviceObjectIDs from IPortableDeviceContent2, hr = 0x%lx\n",hr);
    }

    // Loop calling Next() while S_OK is being returned.
    while(hr == S_OK)
    {
        DWORD  cFetched = 0;
        PWSTR  szObjectIDArray[NUM_OBJECTS_TO_REQUEST] = {0};
        hr = pEnumObjectIDs->Next(NUM_OBJECTS_TO_REQUEST,   // Number of objects to request on each NEXT call
                                  szObjectIDArray,          // Array of PWSTR array which will be populated on each NEXT call
                                  &cFetched);               // Number of objects written to the PWSTR array
        if (SUCCEEDED(hr))
        {
            // Traverse the results of the Next() operation and recursively enumerate
            // Remember to free all returned object identifiers using CoTaskMemFree()
            for (DWORD dwIndex = 0; dwIndex < cFetched; dwIndex++)
            {
                RecursiveEnumerate(szObjectIDArray[dwIndex],pContent);

                // Free allocated PWSTRs after the recursive enumeration call has completed.
                CoTaskMemFree(szObjectIDArray[dwIndex]);
                szObjectIDArray[dwIndex] = NULL;
            }
        }
    }
}

IEnumPortableDeviceObjectIDs

IPortableDeviceContent2-Schnittstelle

IPortableDeviceService-Schnittstelle

Öffnen eines Diensts

WpdServicesApiSample