C#连接android时,pc端检测便携设备PortableDeviceApi调用的问题
2015-11-04 18:22
1511 查看
看过很多blog,也各种搜集链接,但是想好好的整理一下自己的开发历程,就打算开博写东西,空了把以前的项目问题搬上来。
2015.11.04 这是一个值得纪念的日子。
问题描述:
目前正在着手弄一个android 平板用数据线连接的问题,怎么实现连接先搁置一下,谈一下这两天想破头的问题。
正式由于平板的插拔问题,为了反正意外的掉线问题,必须时刻保持对设备与主机连接状态的检测,所以我希望通过pc端定时获取当前连接的便携设备。
历程: 最开始的时候,我不知道当前用的平板是便携设备,以为通过简单的usb 插拔消息句柄可以控制,然后获取C#中用 driverInfo 封装好的设备信息。
后来在各种更改driverType后仍然检测不到已经插好的android 平板,遂通过设备管理器查看才知道其显示为便携设备,并不具备盘符,无法通过driverInfo获取。
然后又在各种百度下,才知道便携设备的检测需要用到 Windows PortableDeviceApi. 既然有api是肯定好的,但是问题总是一堆一堆的。
首先网上相关的资料不算太多,同时微软msdn文档中用的是C++的方法,并不满足我的需求。后来才找到几个链接接近我的想法。http://blog.csdn.net/yu0zhuo/article/details/5728605/、、、、、、、http://blogs.msdn.com/b/dimeby8/archive/2006/12/05/enumerating-wpd-devices-in-c.aspx
本来想直接使用第一个链接中的代码,无奈编译出错,主要问题出在 devMgr.GetDevices(strPnPDeviceIDs, ref cDevices)这个方法中,官方api第一个参数类型为 string,
而代码中为string[],显然这是不匹配的,但是又不知道怎么解决,遂科普到第二个链接,由于英文水平不太好的问题,折腾半天才看到
Mike R. brought to my notice that the above sample only enumerates one device even if more than one are connected. This is a marshalling restriction - we can work around it by manually fixing up the generated Interop assembly. Follow the steps below to edit
the assembly:
Disassemble the PortableDeviceApi interop using the command -
ildasm Interop.PortableDeviceApiLib.dll /out:pdapi.il
Open the IL in Notepad and search for the following string
instance void GetDevices([in][out] string& marshal( lpwstr) pPnPDeviceIDs,
Replace all instances of the string above with the following string
instance void GetDevices([in][out] string[] marshal([]) pPnPDeviceIDs,
Save the IL and reassemble the interop using the command -
ilasm pdapi.il /dll /output=Interop.PortableDeviceApiLib.dll
You can now rebuild your project. You can now first call GetDevices with a NULL parameter to get the count of devices and then call it again with an array to get the device IDs.
这是在告诉我们,使用官方原定的api有局限性,不支持 string[] 那个类型的参数,需要我们手工改动PortableDeviceApiLib的dll文件,修改其中的方法 GetDevices([in][out] string[] marshal([]) pPnPDeviceIDs)
关键之处:先把原来的PortableDeviceApiLib.dll用(ILDASM)反编译,得到PortableDeviceApiLib.il ,然后修改文中的代码:
修改方式为 将文件中的instance void GetDevices([in][out] string& marshal( lpwstr) pPnPDeviceIDs 替换为
instance void GetDevices([in][out] string[] marshal([]) pPnPDeviceIDs,
然后回到程序界面,编译问题消失,貌似得以解决。
再然后,问题又来了,当调试程序时,爆出了另一个错误 Marshaler restriction: Excessively long string.
这个问题使得程序执行到getDevice时终止。又各种查阅,才知道参数依旧不匹配,继续修改参数
修改方式为:将文件中的instance void GetDevices([in][out] string& marshal( lpwstr) pPnPDeviceIDs
替换为 instance void GetDevices([in][out] string[] marshal(lpwstr) pPnPDeviceIDs,
目前的问题初步得到解决。
2015.11.04 这是一个值得纪念的日子。
问题描述:
目前正在着手弄一个android 平板用数据线连接的问题,怎么实现连接先搁置一下,谈一下这两天想破头的问题。
正式由于平板的插拔问题,为了反正意外的掉线问题,必须时刻保持对设备与主机连接状态的检测,所以我希望通过pc端定时获取当前连接的便携设备。
历程: 最开始的时候,我不知道当前用的平板是便携设备,以为通过简单的usb 插拔消息句柄可以控制,然后获取C#中用 driverInfo 封装好的设备信息。
后来在各种更改driverType后仍然检测不到已经插好的android 平板,遂通过设备管理器查看才知道其显示为便携设备,并不具备盘符,无法通过driverInfo获取。
然后又在各种百度下,才知道便携设备的检测需要用到 Windows PortableDeviceApi. 既然有api是肯定好的,但是问题总是一堆一堆的。
首先网上相关的资料不算太多,同时微软msdn文档中用的是C++的方法,并不满足我的需求。后来才找到几个链接接近我的想法。http://blog.csdn.net/yu0zhuo/article/details/5728605/、、、、、、、http://blogs.msdn.com/b/dimeby8/archive/2006/12/05/enumerating-wpd-devices-in-c.aspx
本来想直接使用第一个链接中的代码,无奈编译出错,主要问题出在 devMgr.GetDevices(strPnPDeviceIDs, ref cDevices)这个方法中,官方api第一个参数类型为 string,
而代码中为string[],显然这是不匹配的,但是又不知道怎么解决,遂科普到第二个链接,由于英文水平不太好的问题,折腾半天才看到
Mike R. brought to my notice that the above sample only enumerates one device even if more than one are connected. This is a marshalling restriction - we can work around it by manually fixing up the generated Interop assembly. Follow the steps below to edit
the assembly:
Disassemble the PortableDeviceApi interop using the command -
ildasm Interop.PortableDeviceApiLib.dll /out:pdapi.il
Open the IL in Notepad and search for the following string
instance void GetDevices([in][out] string& marshal( lpwstr) pPnPDeviceIDs,
Replace all instances of the string above with the following string
instance void GetDevices([in][out] string[] marshal([]) pPnPDeviceIDs,
Save the IL and reassemble the interop using the command -
ilasm pdapi.il /dll /output=Interop.PortableDeviceApiLib.dll
You can now rebuild your project. You can now first call GetDevices with a NULL parameter to get the count of devices and then call it again with an array to get the device IDs.
这是在告诉我们,使用官方原定的api有局限性,不支持 string[] 那个类型的参数,需要我们手工改动PortableDeviceApiLib的dll文件,修改其中的方法 GetDevices([in][out] string[] marshal([]) pPnPDeviceIDs)
关键之处:先把原来的PortableDeviceApiLib.dll用(ILDASM)反编译,得到PortableDeviceApiLib.il ,然后修改文中的代码:
修改方式为 将文件中的instance void GetDevices([in][out] string& marshal( lpwstr) pPnPDeviceIDs 替换为
instance void GetDevices([in][out] string[] marshal([]) pPnPDeviceIDs,
然后回到程序界面,编译问题消失,貌似得以解决。
再然后,问题又来了,当调试程序时,爆出了另一个错误 Marshaler restriction: Excessively long string.
这个问题使得程序执行到getDevice时终止。又各种查阅,才知道参数依旧不匹配,继续修改参数
修改方式为:将文件中的instance void GetDevices([in][out] string& marshal( lpwstr) pPnPDeviceIDs
替换为 instance void GetDevices([in][out] string[] marshal(lpwstr) pPnPDeviceIDs,
目前的问题初步得到解决。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories