Поделиться через


Изучение устройства

Изучение устройства аналогично изучению диска. Все объекты на устройстве называются хранилищами. Хранилище может быть файлом, папкой или абстрактным объектом (например, списком воспроизведения) на устройстве. Чтобы понять, какой тип хранилища он имеет, необходимо проверить атрибуты и метаданные хранилища (если оно поддерживается). Хранилища организованы иерархически на устройстве; у каждого хранилища есть ровно один родитель, и все хранилища в конечном итоге происходят от одного корневого хранилища устройства, как правило, называемого "\".

Ниже описано, как изучить устройство.

  1. Получите интерфейс IWMDMDevice устройства, как описано в Перечисление устройств.
  2. Вызовите IWMDMDevice::EnumStorage, чтобы получить интерфейс IWMDMEnumStorage. Этот интерфейс используется для получения всех дочерних объектов хранилища, которое предоставляет этот интерфейс. При получении этого интерфейса с устройства, как в данном случае, он будет хранить только одно хранилище: корневое хранилище устройства.
  3. Вызовите IWMDMEnumStorage::Next со значением 1, чтобы получить интерфейс IWMDMStorage для корневого хранилища устройств. Вы не можете запросить более одного объекта на устройстве.
  4. Проверьте все хранилища на устройстве, рекурсивно вызывая IWMDMStorage::EnumStorage, а затем IWMDMEnumStorage::Next, тем самым получая дочерние элементы хранилища. Чтобы проверить, есть ли у хранилища дочерние элементы, во избежание вызовов EnumStorage и Next, можно вызвать IWMDMStorage::GetAttributes, чтобы проверить флаги WMDM_STORAGE_ATTR_HAS_FILES или WMDM_STORAGE_ATTR_HAS_FOLDERS. Дополнительные сведения о том, как получить свойства хранилища, см.: Получение и настройка метаданных и атрибутов и Получение и настройка метаданных и атрибутов в приложении.

Диспетчер устройств Windows Media не предоставляет стандартный набор папок для хранения носителя определенного типа (например, папки "Мои списки воспроизведения" для списков воспроизведения). Каждое устройство имеет уникальную файловую систему, и вам придется выбрать подходящее место для поиска или отправить определенный файл.

Заметка

Обозреватель Windows может отображать виртуальные папки, которые на самом деле не существуют на устройстве. Примером виртуальных папок являются папки Media и Data, отображаемые для устройств MTP. Эти папки создаются 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