访问某个特定的设备,例如我们自己开发的一个驱动,基本的方法如下:
使用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)
{
可以做些初始化类的事情
}
}
}
});
});