枚举 Windows Media 设备管理器 设备
对应用程序进行身份验证后,你可以开始枚举 Windows Media 设备管理器检测到的设备。 枚举通过使用 IWMDeviceManager2::EnumDevices2 或 IWMDeviceManager::EnumDevices 获取的枚举接口 IWMDMEnumDevice 来完成。 如果受支持,请使用 EnumDevices2 方法,因为早期版本仅在设备上返回旧版接口,而新版本返回旧接口和新接口。
在获取枚举器之前,应确定要使用的枚举视图。 某些设备将每个存储公开为不同的设备。 例如,设备上的两个闪存卡将枚举,就好像它们是单独的设备一样。 可以指定将设备上的所有存储一起枚举为单个设备。 只能在应用程序中设置此首选项一次;如果要更改它,则必须关闭应用程序并重新启动它。 但请注意,旧设备有时会忽略将单独的设备存储枚举为单个设备的请求,并继续单独枚举它们。
以下步骤演示如何枚举连接的设备:
- 使用 IWMDeviceManager3::SetDeviceEnumPreference 设置设备枚举首选项。 如果未调用此方法,则默认方法是将存储显示为单独的设备。 若要确定单个“设备”是否实际上是同一设备上的存储,请调用 IWMDMDevice2::GetCanonicalName;同一设备的存储将返回相同的值,但最后一个“$”符号后的最后一个数字除外。
- 查询 IWMDeviceManager 或 IWMDeviceManager2,然后调用 IWMDeviceManager2::EnumDevices2 以获取设备枚举器接口 IWMDMEnumDevice。 (如果受支持,请使用 EnumDevices2,这会更高效,因为早期版本可能不会) 返回 MTP 设备。
- 调用 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;
}
相关主题