列舉 Windows 媒體裝置管理員裝置
驗證應用程式之後,您就可以開始列舉 Windows 媒體裝置管理員偵測到的裝置。 列舉是透過使用IWMDeviceManager2::EnumDevices2::EnumDevices2或IWMDeviceManager::EnumDevices::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;
}
相關主題