列舉 Windows 媒體設備管理器裝置
驗證應用程式之後,您可以開始列舉 Windows 媒體設備管理器偵測到的裝置。 列舉是透過使用列舉介面 IWMDMEnumDevice來完成,這個介面是可使用 IWMDeviceManager2::EnumDevices2 或 IWMDeviceManager::EnumDevices獲得的。 如果支援,請使用 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;
}
相關主題