物件標識碼只保證為指定裝置會話的唯一標識符;如果使用者建立新的連線,則來自上一個會話的標識碼可能不符合目前會話的標識碼。 若要解決此問題,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 identifier.
printf("Enter the Persistent 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);
}
}
相關主題