Auflisten von Windows Media-Geräte-Manager-Geräten

Nach der Authentifizierung einer Anwendung können Sie damit beginnen, die von Windows Media Geräte-Manager erkannten Geräte aufzulisten. Die Enumeration erfolgt mithilfe der Enumerationsschnittstelle IWMDMEnumDevice, die entweder mit IWMDeviceManager2::EnumDevices2 oder IWMDeviceManager::EnumDevices abgerufen wird. Falls unterstützt, verwenden Sie die EnumDevices2-Methode , da die frühere Version nur Legacyschnittstellen auf Geräten zurückgegeben hat, während die neue Version sowohl die legacy als auch die neuen Schnittstellen zurückgibt.

Bevor Sie einen Enumerator abrufen, sollten Sie entscheiden, welche Enumerationsansicht verwendet werden soll. Einige Geräte machen jeden Speicher als ein anderes Gerät verfügbar. Beispielsweise werden zwei Flash-Speicherkarten auf einem Gerät aufgezählt, als wären sie separate Geräte. Sie können angeben, dass alle Speicher auf einem Gerät als einzelnes Gerät aufgelistet werden. Sie können diese Einstellung nur einmal in Ihrer Anwendung festlegen. Wenn Sie sie ändern möchten, müssen Sie die Anwendung herunterfahren und neu starten. Beachten Sie jedoch, dass ältere Geräte manchmal eine Anforderung zum Aufzählen separater Gerätespeicher als einzelnes Gerät ignorieren und weiterhin separat auflisten.

Die folgenden Schritte zeigen, wie verbundene Geräte aufgelistet werden:

  1. Legen Sie die Einstellung für die Geräteenumeration mithilfe von IWMDeviceManager3::SetDeviceEnumPreference fest. Wenn diese Methode nicht aufgerufen wird, besteht die Standardmethode darin, Speicher als separate Geräte anzuzeigen. Rufen Sie IWMDMDevice2::GetCanonicalName auf, um festzustellen, ob es sich bei einzelnen "Geräten" tatsächlich um Speicher auf demselben Gerät handelt. Speicher vom gleichen Gerät geben identische Werte zurück, mit Ausnahme der letzten Ziffer nach dem letzten "$"-Zeichen.
  2. Fragen Sie IWMDeviceManager oder IWMDeviceManager2 ab, und rufen Sie dann IWMDeviceManager2::EnumDevices2 auf, um die Geräteenumeratorschnittstelle IWMDMEnumDevice abzurufen. (Falls unterstützt, verwenden Sie EnumDevices2, was effizienter ist, da die frühere Version möglicherweise keine MTP-Geräte zurückgibt.)
  3. Rufen Sie die IWMDMEnumDevices::Next-Methode auf, um ein oder mehrere Geräte gleichzeitig abzurufen. Fahren Sie mit dem Aufrufen dieser Methode fort, bis die Methode S_FALSE oder eine Fehlermeldung zurückgibt. Wenn Sie jeweils nur ein Gerät abrufen, müssen Sie kein Array für die Geräte zuordnen.

Da Benutzer Geräte vom Computer anfügen oder entfernen können, während Ihre Anwendung ausgeführt wird, empfiehlt es sich, eine Benachrichtigung über die Geräteverbindung oder -entfernung zu implementieren. Dazu wird die IWMDMNotification-Schnittstelle implementiert und registriert. Weitere Informationen hierzu finden Sie unter Aktivieren von Benachrichtigungen.

Der folgende C++-Code listet Geräte auf und fordert Informationen zu jedem Gerät an.

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;
}

Erstellen einer Windows Media Geräte-Manager-Anwendung