共用方式為


列舉 Windows 媒體裝置管理員裝置

驗證應用程式之後,您就可以開始列舉 Windows 媒體裝置管理員偵測到的裝置。 列舉是透過使用IWMDeviceManager2::EnumDevices2::EnumDevices2IWMDeviceManager::EnumDevices::EnumDevices取得的列舉介面 IWMDMEnumDevice 來完成。 如果支援,請使用 EnumDevices2 方法,因為舊版只在裝置上傳回舊版介面,而新版本則會同時傳回舊版和新介面。

取得列舉值之前,您應該先決定要使用的列舉檢視。 有些裝置會將每個存放裝置公開為不同的裝置。 例如,裝置上的兩張快閃記憶卡會列舉,就像是個別的裝置一樣。 您可以指定裝置上的所有儲存體都會一起列舉為單一裝置。 您只能在應用程式中設定此喜好設定一次;如果您想要變更它,您必須關閉應用程式並重新啟動它。 不過,請注意,舊版裝置有時會忽略將個別裝置儲存體列舉為單一裝置的要求,並繼續個別列舉它們。

下列步驟示範如何列舉連線的裝置:

  1. 使用 IWMDeviceManager3::SetDeviceEnumPreference 設定裝置列舉喜好設定。 如果未呼叫此方法,預設方法是將儲存體顯示為個別裝置。 若要判斷個別的「裝置」是否實際儲存在相同的裝置上,請呼叫 IWMDMDevice2::GetCanonicalName;來自相同裝置的儲存體會傳回相同的值,但最後一個 「$」 符號之後的最後一個數位除外。
  2. 查詢 IWMDeviceManagerIWMDeviceManager2,然後呼叫 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 媒體裝置管理員應用程式