Aufzählen 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 aufzuzählen. Die Enumeration erfolgt mithilfe einer Enumerationsschnittstelle, IWMDMEnumDevice,die entweder mithilfe von IWMDeviceManager2::EnumDevices2 oder IWMDeviceManager::EnumDevicesabgerufen 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 Legacyschnittstelle 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 Flashspeicherkarten auf einem Gerät so aufzählen, als wären es separate Geräte. Sie können angeben, dass alle Speicher auf einem Gerät als einzelnes Gerät aufzählt 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 ignorieren, separate Gerätespeicher als einzelnes Gerät aufzuzählen und sie weiterhin separat aufzuzählen.

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

  1. Legen Sie die Einstellung für die Geräteenumeration mithilfe von IWMDeviceManager3::SetDeviceEnumPreferencefest. Wenn diese Methode nicht aufgerufen wird, besteht die Standardmethode darin, Speicher als separate Geräte anzuzeigen. Um zu bestimmen, ob einzelne "Geräte" tatsächlich Speicher auf demselben Gerät sind, rufen Sie IWMDMDevice2::GetCanonicalName auf. Speicher vom gleichen Gerät geben identische Werte zurück, mit Ausnahme der letzten Ziffer nach dem letzten "$"-Zeichen.
  2. Fragen Sie IWMDeviceManager oder IWMDeviceManager2ab, und rufen Sie dann IWMDeviceManager2::EnumDevices2 auf, um die Geräteenumeratorschnittstelle IWMDMEnumDeviceabzurufen. (Wenn dies unterstützt wird, 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 mindestens ein Gerät 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 an den Computer anfügen oder entfernen können, während Ihre Anwendung ausgeführt wird, ist es eine gute Idee, eine Benachrichtigung über die Geräteverbindung oder das Entfernen zu implementieren. Hierzu 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