从持久唯一 ID 检索对象 ID

仅保证给定设备会话的对象标识符是唯一的;如果用户建立了新连接,则来自上一个会话的标识符可能与当前会话的标识符不匹配。 为了解决此问题,WPD API 支持持久性唯一标识符 (PUID) ,这些标识符在设备会话中持久存在。

某些设备使用给定对象以本机方式存储其 PUID。 其他人可能会基于所选对象数据的哈希生成 PUID。 其他人可能会将对象标识符视为 PUID (,因为它们可以保证这些标识符永远不会) 更改。

ContentProperties.cpp 模块中的 GetObjectIdentifierFromPersistentUniqueIdentifier 函数演示如何检索给定 PUID 的对象标识符。

应用程序可以使用下表中所述的接口检索相应的 PUID 的对象标识符。

接口 说明
IPortableDeviceContent 接口 提供对检索方法的访问。
IPortableDevicePropVariantCollection 接口 用于存储对象标识符和相应的永久性唯一标识符 (PUID) 。

 

示例应用程序完成的第一个任务是从用户获取 PUID。

// Prompt user to enter an unique identifier to convert to an object idenifier.
printf("Enter the Persistant Unique Identifier of the object you wish to convert into an object identifier.\n>");
hr = StringCbGetsW(szSelection,sizeof(szSelection));
if (FAILED(hr))
{
    printf("An invalid persistent object identifier was specified, aborting the query operation\n");
}

之后,示例应用程序将检索 IPortableDeviceContent 对象,该对象将用于调用 GetObjectIDsFromPersistentUniqueIDs 方法。

if (SUCCEEDED(hr))
{
    hr = pDevice->Content(&pContent);
    if (FAILED(hr))
    {
        printf("! Failed to get IPortableDeviceContent from IPortableDevice, hr = 0x%lx\n",hr);
    }
}

接下来,它将创建一个 IPortableDevicePropVariantCollection 对象,该对象将保存用户提供的 PUID。

hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection,
                      NULL,
                      CLSCTX_INPROC_SERVER,
                      IID_PPV_ARGS(&pPersistentUniqueIDs));

执行前三个步骤后,示例即可检索与用户提供的 PUID 匹配的对象标识符。 这是通过调用 IPortableDeviceContent::GetObjectIDsFromPersistentUniqueIDs 方法实现的。 在调用此方法之前,该示例初始化 PROPVARIANT 结构,将用户提供的 PUID 写入此结构,并将其添加到 pPersistentUniqueIDs 指向的 IPortableDevicePropVariantCollection 对象。 此指针作为第一个参数传递到 GetObjectIDsFromPersistentUniqueIDs 方法。 GetObjectIDsFromPersistentUniqueIDs 的第二个参数是接收匹配对象标识符的 IPortableDevicePropVariantCollection 对象。

if (SUCCEEDED(hr))
{
    if (pPersistentUniqueIDs != NULL)
    {
        PROPVARIANT pv = {0};
        PropVariantInit(&pv);

        // Initialize a PROPVARIANT structure with the object identifier string
        // that the user selected above. Notice we are allocating memory for the
        // PWSTR value.  This memory will be freed when PropVariantClear() is
        // called below.
        pv.vt      = VT_LPWSTR;
        pv.pwszVal = AtlAllocTaskWideString(szSelection);
        if (pv.pwszVal != NULL)
        {
            // Add the object identifier to the objects-to-delete list
            // (We are only deleting 1 in this example)
            hr = pPersistentUniqueIDs->Add(&pv);
            if (SUCCEEDED(hr))
            {
                // 3) Attempt to get the unique idenifier for the object from the device
                hr = pContent->GetObjectIDsFromPersistentUniqueIDs(pPersistentUniqueIDs,
                                                                   &pObjectIDs);
                if (SUCCEEDED(hr))
                {
                    PROPVARIANT pvId = {0};
                    hr = pObjectIDs->GetAt(0, &pvId);
                    if (SUCCEEDED(hr))
                    {
                        printf("The persistent unique identifier '%ws' relates to object identifier '%ws' on the device.\n", szSelection, pvId.pwszVal);
                    }
                    else
                    {
                        printf("! Failed to get the object identifier for '%ws' from the IPortableDevicePropVariantCollection, hr = 0x%lx\n",szSelection, hr);
                    }

                    // Free the returned allocated string from the GetAt() call
                    PropVariantClear(&pvId);
                }
                else
                {
                    printf("! Failed to get the object identifier from persistent object idenifier '%ws', hr = 0x%lx\n",szSelection, hr);
                }
            }
            else
            {
                printf("! Failed to get the object identifier from persistent object idenifier because we could no add the persistent object identifier string to the IPortableDevicePropVariantCollection, hr = 0x%lx\n",hr);
            }
        }
        else
        {
            hr = E_OUTOFMEMORY;
            printf("! Failed to get the object identifier because we could no allocate memory for the persistent object identifier string, hr = 0x%lx\n",hr);
        }

        // Free any allocated values in the PROPVARIANT before exiting
        PropVariantClear(&pv);
    }
}

IPortableDevice 接口

IPortableDeviceContent 接口

IPortableDevicePropVariantCollection 接口

编程指南