当先锋百科网

首页 1 2 3 4 5 6 7

看过很多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:

  1. Disassemble the PortableDeviceApi interop using the command -
    ildasm Interop.PortableDeviceApiLib.dll /out:pdapi.il
  2. Open the IL in Notepad and search for the following string
    instance void  GetDevices([in][out] string&  marshal( lpwstr) pPnPDeviceIDs,
  3. Replace all instances of the string above with the following string
    instance void  GetDevices([in][out] string[]  marshal([]) pPnPDeviceIDs,
  4. 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,

目前的问题初步得到解决。