从持久唯一 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);
}
}
相关主题