訪問某個特定的設備,例如我們自己開發的一個驅動,基本的方法如下:
使用DeviceInformationCollection查詢到該設備的ID,再使用CreateDeviceAccessInstance函數創建一個ICreateDeviceAccessAsync,再得到IDeviceIoControl接口,就可以調用其提供的DeviceIoControl方法再調用設備。
需要注意的是,DeviceInformation::FindAllAsync函數是異步的,需要創建一個task來調用。Metro中的方法實在讓人覺得奇怪,尤其是讓我這個習慣了C語言的老人,好在微軟提供了例子代碼。寫這點文字的時候我還沒有明白這些用法,按如下代碼做就行了。同時因為查找設備的過程與界面(一般而言應該是界面啟動時調用這個查找過程)是異步的,當設備節點查找到,並打開它時,界面早已經加載完了。如果界面上某些狀態依賴於對這個驅動的操作,就需要在打開設備時再設置一下界面的狀態。
還有一點,基於Metro開發的程序要訪問驅動程序,還需要設置對應的Metadata.
static ICreateDeviceAccessAsync *createAsync=nullptr;
static IDeviceIoControl * devicePort=nullptr;
task<DeviceInformationCollection^>(DeviceInformation::FindAllAsync( "System.Devices.InterfaceClassGuid:=\"設備的Interface ID\"" ))
.then([this](DeviceInformationCollection^ interfaces )
{
for_each(begin(interfaces), end(interfaces),
[this](DeviceInformation^ deviceInterface)
{
HRESULT hr;
if( !devicePort )
{
hr=CreateDeviceAccessInstance( deviceInterface->Id->Data( ) , GENERIC_READ | GENERIC_WRITE , &createAsync );
if( S_OK == hr )
{
hr = createAsync->Wait(INFINITE);
hr = createAsync->GetResult(IID_PPV_ARGS(&devicePort));
if( S_OK ==hr)
{
可以做些初始化類的事情
}
}
}
});
});
