枚举服务内容

应用程序打开服务后,可以开始执行与服务相关的操作。 对于 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