다음을 통해 공유


Windows Media 장치 관리자 디바이스 열거

애플리케이션을 인증한 후 Windows Media 장치 관리자 검색된 디바이스를 열거하기 시작할 수 있습니다. 열거형은 IWMDeviceManager2::EnumDevices2 또는 IWMDeviceManager::EnumDevices를 사용하여 가져온 열거형 인터페이스 IWMDMEnumDevice를 사용하여 수행됩니다. 지원되는 경우 이전 버전이 디바이스에서 레거시 인터페이스만 반환한 반면 새 버전은 레거시 인터페이스와 새 인터페이스를 모두 반환하므로 EnumDevices2 메서드를 사용합니다.

열거자를 가져오기 전에 사용할 열거형 보기를 결정해야 합니다. 일부 디바이스는 각 스토리지를 다른 디바이스로 노출합니다. 예를 들어 디바이스에 있는 두 개의 플래시 메모리 카드는 별도의 디바이스인 것처럼 열거됩니다. 디바이스의 모든 스토리지가 단일 디바이스로 함께 열거되도록 지정할 수 있습니다. 이 기본 설정은 애플리케이션에서 한 번만 설정할 수 있습니다. 변경하려면 애플리케이션을 종료하고 다시 시작해야 합니다. 그러나 레거시 디바이스는 개별 디바이스 스토리지를 단일 디바이스로 열거하는 요청을 무시하고 별도로 열거하는 경우가 있습니다.

다음 단계에서는 연결된 디바이스를 열거하는 방법을 보여줍니다.

  1. IWMDeviceManager3::SetDeviceEnumPreference를 사용하여 디바이스 열거형 기본 설정을 지정합니다. 이 메서드를 호출하지 않으면 기본 방법은 스토리지를 별도의 디바이스로 표시하는 것입니다. 개별 "디바이스"가 실제로 동일한 디바이스의 스토리지인지 확인하려면 IWMDMDevice2::GetCanonicalName을 호출합니다. 동일한 디바이스의 스토리지는 마지막 "$" 기호 뒤의 최종 숫자를 제외하고 동일한 값을 반환합니다.
  2. IWMDeviceManager 또는 IWMDeviceManager2를 쿼리한 다음 IWMDeviceManager2::EnumDevices2를 호출하여 디바이스 열거자 인터페이스인 IWMDMEnumDevice를 가져옵니다. (지원되는 경우 이전 버전이 MTP 디바이스를 반환하지 않을 수 있으므로 더 효율적인 EnumDevices2를 사용합니다.)
  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 장치 관리자 애플리케이션 만들기