共用方式為


列舉服務內容

應用程式開啟服務之後,就可以開始執行服務相關作業。 在 WpdServicesApiSample 應用程式中,其中一項作業是指定連絡人服務的內容列舉。 下表描述所使用的介面。

介面 描述
IPortableDeviceService 用來擷取 IPortableDeviceContent2 介面來存取服務上的內容。
IPortableDeviceContent2 用來擷取 IEnumPortableDeviceObjectIDs 介面,以列舉服務上的物件。
IEnumPortableDeviceObjectIDs 用來列舉服務上的物件。

 

ContentEnumeration.cpp 模組中找到內容列舉程式碼。 此程式碼位於 EnumerateAllContentRecursiveEnumerate 方法中。 先前的方法會呼叫後者。

EnumerateContent方法會採用IPortableDeviceService物件的指標做為其一個參數。 此物件會對應至應用程式在呼叫 IPortableDeviceService::Open 方法時稍早開啟的服務。

EnumerateContent方法會建立IPortableDeviceContent2物件,並將這個物件傳遞至IPortableDeviceService::Content方法。 這個方法接著會擷取服務根層級的內容,然後以遞迴方式開始擷取根底下找到的內容。

下列程式碼會對應至 EnumerateContent 方法。

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

下列程式碼會對應至 RecursiveEnumerate 方法。 RecursiveEnumerate 方法會具現化所提供父物件的 IEnumPortableDeviceObjectIDs 介面,並呼叫 IEnumPortableDeviceObjectIDs::Next,擷取一批立即子物件。 針對每個子物件,會再次呼叫 RecursiveEnumerate 以傳回其子系子物件,依此類歸。

// 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 介面

IPortableDeviceService 介面

開啟服務

WpdServicesApiSample