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


Перечисление устройств Windows Media диспетчер устройств

После проверки подлинности приложения можно начать перечисление устройств, обнаруженных диспетчер устройств Windows Media. Перечисление выполняется с помощью интерфейса перечисления IWMDMEnumDevice, полученного с помощью IWMDeviceManager2::EnumDevices2 или IWMDeviceManager::EnumDevices. Если поддерживается, используйте метод EnumDevices2 , так как более ранняя версия возвращала только устаревшие интерфейсы на устройствах, тогда как новая версия возвращает как устаревшие, так и новые интерфейсы.

Перед получением перечислителя необходимо решить, какое представление перечисления следует использовать. Некоторые устройства предоставляют каждое хранилище как отдельное устройство. Например, две карты флэш-памяти на устройстве будут перечисляться так, как если бы они были отдельными устройствами. Можно указать, что все хранилища на устройстве перечисляются вместе как одно устройство. Этот параметр можно задать только один раз в приложении; Если вы хотите изменить его, необходимо завершить работу приложения и перезапустить его. Однако обратите внимание, что устаревшие устройства иногда игнорируют запрос на перечисление отдельных хранилищ устройств как одного устройства и продолжают перечислять их отдельно.

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

  1. Задайте параметры перечисления устройств с помощью IWMDeviceManager3::SetDeviceEnumPreference. Если этот метод не вызывается, то по умолчанию хранилища отображаются как отдельные устройства. Чтобы определить, являются ли отдельные устройства хранилищами на одном устройстве, вызовите IWMDMDevice2::GetCanonicalName; хранилища с того же устройства будут возвращать одинаковые значения, за исключением последней цифры после последнего знака "$".
  2. Запросите IWMDeviceManager или IWMDeviceManager2, а затем вызовите IWMDeviceManager2::EnumDevices2 , чтобы получить интерфейс перечислителя устройств IWMDMEnumDevice. (Если это поддерживается, используйте EnumDevices2, что более эффективно, так как более ранняя версия может не возвращать устройства MTP.
  3. Вызовите метод IWMDMEnumDevices::Next , чтобы получить одно или несколько устройств за раз. Продолжайте вызывать этот метод, пока метод не вернет S_FALSE или сообщение об ошибке. При одновременном получении только одного устройства не требуется выделять массив для хранения устройств.

Так как пользователи могут подключать или удалять устройства с компьютера во время работы приложения, рекомендуется реализовать уведомление о подключении или удалении устройства. Это делается путем реализации интерфейса IWMDMNotification и его регистрации. Дополнительные сведения об этом см. в разделе Включение уведомлений.

Следующий код C++ перечисляет устройства и запрашивает сведения о каждом устройстве.

HRESULT CWMDMController::EnumDevices()
{
    HRESULT hr = S_OK;

    // Change behavior to show devices as one object, not each storage as a device.
    // This can be called only once for each instance of this application.
    CComQIPtr<IWMDeviceManager3>pDevMgr3(m_IWMDMDeviceMgr);
    hr = pDevMgr3->SetDeviceEnumPreference(DO_NOT_VIRTUALIZE_STORAGES_AS_DEVICES);
    
    // Get number of attached devices.
    DWORD iDevices = 0;
    hr = m_IWMDMDeviceMgr->GetDeviceCount(&iDevices);
    if (hr == S_OK)
    {
        // TODO: Display count of devices.
    }

    //
    // Get a device enumerator to enumerate devices.
    //
    CComPtr<IWMDeviceManager2> pDevMgr2;
    hr = m_IWMDMDeviceMgr->QueryInterface (__uuidof(IWMDeviceManager2), (void**) &pDevMgr2);
    if (hr == S_OK)
    {
        // TODO: Display message indicating that application obtained IWMDeviceManager2.
    }
    else
    {
        // TODO: Display message indicating that we couldn't 
        // get IWMDeviceManager2 in EnumDevices.
        return hr;
    }
   CComPtr<IWMDMEnumDevice> pEnumDevice;
   hr = pDevMgr2->EnumDevices2(&pEnumDevice);
    if (hr != S_OK)
    {
        // TODO: Display messaging indicating that an error occurred 
        // in calling EnumDevices2.
        return hr;
    }

    // Length of all the strings we'll send in. 
    const UINT MAX_CHARS = 100;

    // Iterate through devices.
    while(TRUE)
    {
        // Get a device handle.
        IWMDMDevice *pIWMDMDevice;
        ULONG ulFetched = 0;
        hr = pEnumDevice->Next(1, &pIWMDMDevice, &ulFetched);
        if ((hr != S_OK) || (ulFetched != 1))
        {
            break;
        }
        
        // Get a display icon for the device.
        ULONG deviceIcon = 0;
        hr = pIWMDMDevice->GetDeviceIcon(&deviceIcon);

        // Print the device manufacturer.
        WCHAR manufacturer[MAX_CHARS];
        hr = pIWMDMDevice->GetManufacturer((LPWSTR)&manufacturer, MAX_CHARS);
        if (hr == S_OK)
        {
            // TODO: Display manufacturer name.
        }

        // Get the device name.
        WCHAR name[MAX_CHARS];
        hr = pIWMDMDevice->GetName((LPWSTR)&name, MAX_CHARS);
        if (hr == S_OK)
        {
            // TODO: Display name.
        }

        // TODO: Get other device information if wanted.

        // Obtain an IWMDMDevice2 interface and call some methods.
        CComQIPtr<IWMDMDevice2> pIWMDMDevice2(pIWMDMDevice);
        if (pIWMDMDevice2 != NULL)
        {
            // Get the canonical name.
            WCHAR canonicalName[MAX_CHARS];
            hr = pIWMDMDevice2->GetCanonicalName(canonicalName, MAX_CHARS);
            if (hr == S_OK)
            {
                // TODO: Display canonical name.
            }
        }

        // Obtain an IWMDMDevice3 interface and call some methods.
        CComQIPtr<IWMDMDevice3>pIWMDMDevice3(pIWMDMDevice);
        if (pIWMDMDevice3 != NULL)
        {
            // Find out what protocol is being used.
            PROPVARIANT val;
            PropVariantInit(&val);
            hr = pIWMDMDevice3->GetProperty(g_wszWMDMDeviceProtocol, &val);

            if (hr == S_OK)
            {
                if (*val.puuid == WMDM_DEVICE_PROTOCOL_RAPI)
                {
                    // TODO: Display message indicating device is a RAPI device.
                }
                else if (*val.puuid == WMDM_DEVICE_PROTOCOL_MTP)
                {
                    / /TODO: Display message indicating device is an MTP device.
                }
                else if (*val.puuid == WMDM_DEVICE_PROTOCOL_MSC)
                {
                    // TODO: Display message indicating device is an MSC device.
                }
                else
                {
                    // TODO: Display message indicating that the 
                    // application encountered an unknown protocol.
                }
                PropVariantClear(&val);
            }
        }

        // Examine the device capabilities. You could use some of these
        // to enable or disable the application's UI elements.
        CComQIPtr<IWMDMDeviceControl> pDeviceControl(pIWMDMDevice);
        if (pDeviceControl != NULL)
        {
            DWORD caps = 0;
            hr = pDeviceControl->GetCapabilities(&caps);
            if (caps & WMDM_DEVICECAP_CANPLAY)
            {
                // TODO: Display message indicating that the media 
                // device can play MP3 audio.
            }
            // TODO: Test for other capabilities here.
        }
    } // Get the next device.
    return hr;
}

Создание приложения диспетчер устройств Windows Media