浏览设备

浏览设备类似于浏览磁盘驱动器。 设备上的所有对象称为 存储。 存储可以是文件、文件夹或抽象对象 (,例如设备上的播放列表) 。 必须检查存储的属性和元数据 ((如果支持)) 以了解存储的类型。 存储在设备上按层次结构进行组织;每个存储只有一个父存储,所有存储最终都从单个根设备存储(通常名为“\”)下降。

以下步骤介绍如何浏览设备:

  1. 获取设备的 IWMDMDevice 接口,如 枚举设备中所述。
  2. 调用 IWMDMDevice::EnumStorage 以检索 IWMDMEnumStorage 接口。 此接口用于获取返回此接口的存储的所有子对象。 从设备获取此接口时,如此处所示,它将只保留一个存储:根设备存储。
  3. 使用计数为 1 调用 IWMDMEnumStorage::Next 以检索根设备存储的 IWMDMStorage 接口。 (不能从 device 请求多个子级。)
  4. 通过以递归方式调用 IWMDMStorage::EnumStorage ,然后 IWMDMEnumStorage::Next 来检查设备上的所有存储以获取存储的子级。 若要查看存储是否具有子级以避免调用 EnumStorageNext,可以调用 IWMDMStorage::GetAttributes 来检查WMDM_STORAGE_ATTR_HAS_FILES或WMDM_STORAGE_ATTR_HAS_FOLDERS标志。 有关如何获取存储属性的详细信息,请参阅 在应用程序中获取和设置元数据和属性获取和设置元数据和属性

Windows Media 设备管理器 不公开一组标准文件夹来保存特定类型的媒体 (例如播放列表的“我的播放列表”文件夹) 。 每台设备都有一个唯一的文件系统,你必须决定查找或发送特定文件的适当位置。

注意

Windows 资源管理器可以显示设备上实际不存在的虚拟文件夹。 示例虚拟文件夹是为 MTP 设备显示的“Media”和“Data”文件夹。 这些文件夹由 Windows 创建,使最终用户的下载更简单;它们实际上不存在于设备上。 应用程序不应依赖于查找这些类型的常规文件夹。 相反,Windows 资源管理器可能不会显示设备上存在的某些文件夹或对象 (例如播放列表) 。

 

以下 C++ 示例代码演示了设备的递归探索。 它使用两个函数:

  • ExploreDevice 是一个启动函数,用于接收设备指针并获取指向该设备的根枚举器的指针。
  • RecursiveExploreStorage,调用它以递归方式浏览设备。
// Get the root enumerator and start the recursive function.
HRESULT ExploreDevice(IWMDMDevice* pDevice)
{
    HRESULT hr = S_OK;

    // Get a root enumerator.
    CComPtr<IWMDMEnumStorage> pEnumStorage;
    hr = pDevice->EnumStorage(&pEnumStorage);
    if (SUCCEEDED(hr))
    {
        RecursiveExploreStorage(pEnumStorage);
    }
    return hr;
}

// Recursively explore a storage.
void RecursiveExploreStorage(IWMDMEnumStorage* pEnumStorage)
{
    HRESULT hr = S_OK;
    CComPtr<IWMDMStorage> pStorage;

    ULONG numRetrieved = 0;
    // Loop through all storages in the current storage.
    while((pEnumStorage->Next(1, &pStorage, &numRetrieved) == S_OK) && (numRetrieved == 1))
    {
        // Get the name of the object.
        const UINT MAX_LEN = 255;
        WCHAR name[MAX_LEN];
        hr = pStorage->GetName((LPWSTR)&name, MAX_LEN);
        // TODO: Display the retrieved storage name

        // If this is a folder, recurse into it.
        if (attributes & WMDM_FILE_ATTR_FOLDER)
        {
            CComPtr<IWMDMEnumStorage> pEnumSubStorage;
            hr = pStorage->EnumStorage(&pEnumSubStorage);
            if (SUCCEEDED(hr)
            {
                RecursiveExploreStorage(pEnumSubStorage);
            }
        }
        pStorage.Release();
    } // Get the next storage pointer.
    return;
}

创建 Windows Media 设备管理器 应用程序