[转]仿91助手的PC与android手机通讯
仿91助手的PC与android手机通讯
原文
知道91助手和豌豆莢吧? 说到这两个东西,最让人好奇的应该是就是和手机的交互了。我之前有研究过电脑和安卓的交互,基本功能已经走通了,在这里我想分享一下。 初初看这个问题觉得很简单,然后如果你有点计算机基础的话深入想一下却发现有很多实现上的空白。
- 检测设备插入
- 检测是否是手机
- 检测是否已经安装驱动
- 自动安装手机驱动
- 获取手机信息
一、检测设备插入
- DBT_CONFIGCHANGECANCELED
- A request to change the current configuration (dock or undock) has been canceled.
- (设备设置取消,我还没怎么研究过这个设置的问题,不过这个跟我现在讲的主题都没关系的。)
- DBT_CONFIGCHANGED
- The current configuration has changed, due to a dock or undock.
- (设备设置变更)
- DBT_CUSTOMEVENT
- A custom event has occurred.
- (这个只是告诉你,设备驱动发出了一个消息)
- DBT_DEVICEARRIVAL
- A device or piece of media has been inserted and is now available.
- (设备或者多媒体插入)
- DBT_DEVICEQUERYREMOVE
- Permission is requested to remove a device or piece of media. Any application can deny this request and cancel the removal.
- (用戶请求弹出设备,返回TRUE允许弹出,返回BROADCAST_QUERY_DENY拒绝弹出,这就是为什么有些时候会发现U盘死活弹不出,非得强拔,这是因为有些进程一直拒绝弹出。)
- DBT_DEVICEQUERYREMOVEFAILED
- A request to remove a device or piece of media has been canceled.
- (请求弹出失败)
- DBT_DEVICEREMOVECOMPLETE
- A device or piece of media has been removed.
- (请求成功)
- DBT_DEVICEREMOVEPENDING
- A device or piece of media is about to be removed. Cannot be denied.
- (强制弹出U盘,这个在360的强制弹出USB时会收到的了)
- DBT_DEVICETYPESPECIFIC
- A device-specific event has occurred.
- (这个是某些个性设备自定义的消息的方法了,自定义部分在LPARAM指针指向的区域中)
- DBT_DEVNODES_CHANGED
- A device has been added to or removed from the system.
- (DevNodes就是设备管理器里面显示的那棵树的节点,这个跟DBT_DEVICEARRIVAL有一点点区别,因为add有可能是因为你新装了某些驱动产生的消息。另外提个醒SAMSUNG手机插入时就是很扑街的收不到DBT_DEVICEARRIVAL类型,只能收到这个。。。)
- DBT_QUERYCHANGECONFIG
- Permission is requested to change the current configuration (dock or undock).
- (请求修改设备设置)
- DBT_USERDEFINED
- The meaning of this message is user-defined.
- (这个类型主要是给用户一个自定义的方法,上面DBT_DEVICETYPESPECIFIC是设备自定义的,这个主要是进程通过BroadcastSystemMessage 来广播的,我还没怎么用过这个玩意。)
好吧,检测设备插入的问题解决了,后面是判断设备是否是手机了。
二、检测是否是手机
上一篇日志说了如何响应设备插入,但是设备有很多中,多媒体设备,鼠标键盘什么的都是,那如何判断是不是USB设备或者是手机插入呢? 这里就介绍一下我自己的研究结果,当然我没有去研究过苹果设备,但是按道理是类似的。
//获取设备信息句柄
HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL,L"USB" ,NULL,DIGCF_ALLCLASSES|DIGCF_PRESENT);
WORD dataType= 0;
DWORD buffSize = 0;
SetupDiGetDeviceRegistryProperty(hDevInfo,&deviceInfoData,SPDRP_COMPATIBLEIDS,&dataType,NULL,buffSize,&buffSize);
int err = GetLastError();
if(err != ERROR_INSUFFICIENT_BUFFER)
return;
LPTSTR szCompatibleID = (LPTSTR)LocalAlloc(LPTR,buffSize+1);
SetupDiGetDeviceRegistryProperty(hDevInfo,&deviceInfoData,SPDRP_COMPATIBLEIDS,&dataType,(PBYTE)szCompatibleID ,buffSize,&buffSize);
//szCompatibleID 即是兼容ID
如果 兼容ID == "usb\\class_ff&subclass_42" 就直接可以知道这个是手机设备了(注意要兼容ID的大小写不确定的)
WORD dataType= 0;
DWORD buffSize = 0;
SetupDiGetDeviceRegistryProperty(hDevInfo,&deviceInfoData,SPDRP_HARDWAREID,&dataType,NULL,buffSize,&buffSize);
int err = GetLastError();
if(err != ERROR_INSUFFICIENT_BUFFER)
return;
LPTSTR szHardwareID = (LPTSTR)LocalAlloc(LPTR,buffSize+1);
SetupDiGetDeviceRegistryProperty(hDevInfo,&deviceInfoData,SPDRP_HARDWAREID,&dataType,(PBYTE)szHardwareID ,buffSize,&buffSize);
//szHardwareID 即是硬件ID
OK,手机判断完成,后面是驱动安装的介绍,手机插入后不一定有驱动,需要有驱动才能进行PC操作手机的功能.
三、检测是否已经安装驱动
上一篇日志说到判断是否是手机设备,但是要与手机进行通讯就必须有驱动程序,否则只能当做“便携储存设备”使用,只能往里面放文件,也许你已经满足了,但 是你想一下91助手只是给你提供存放文件那么简单吗?如果是的话91助手还有鸟用啊?因为我们直接打开“我的电脑”就能打开这个类似U盘的东西了. 再想一想,如果你的程序可以跟手机说"我给个apk你,你安装一下",然后你的手机就装上去了,那不就方便了吗? 这才是卖点~
LPTSTR szInstanceID = NULL
WORD iBuffSize = 0;
SetupDiGetDeviceInstanceId(hDevInfoSet,&deviceInfoData,szInstanceID ,iBuffSize,&iBuffSize ); //获取实例ID的buff需要的大小, hDevInfoSet和deviceInfoData
int err = GetLastError();
if(err != ERROR_INSUFFICIENT_BUFFER)
return;
szInstanceID = (LPTSTR)LocalAlloc(LPTR,buffSize*sizeof(WCHAR)); SetupDiGetDeviceInstanceId(hDevInfoSet,&deviceInfoData,szInstanceID ,iBuffSize ,&iBuffSize ); //获取实例ID
DEVINST deviceInstance;
if (CM_Locate_DevNode(&deviceInstance,szInstanceID ,CM_LOCATE_DEVNODE_NORMAL) == CR_SUCCESS) //获取设备ID对应的设备实例句柄
{
DWORD tatus;
DWORD problemNumber;
if (CM_Get_DevNode_Status(&status,&problemNumber,deviceInstance,0) == CR_SUCCESS)
//获取设备状态和设备状态细节
{
if (!(status&DN_HAS_PROBLEM)) //判断设备是否存在问题,代表驱动已安装
{
//设备无异常,就是说驱动正常
}
else
{
if (problemNumber == CM_PROB_DRIVER_FAILED_PRIOR_UNLOAD
|| problemNumber == CM_PROB_DRIVER_FAILED_LOAD)
{
//设备驱动加载不成功
}
else
{
//有不明原因,可以归结为没安装驱动
}
}
}
}
好吧,驱动是否安装的判断就这样子。一点都不麻烦。
四、自动安装手机驱动
上一节讲到检查驱动安装情况,那么如果遇到没安装手机驱动的话是没办法和手机进行通讯的(除非你是要直接把文件拷贝到手机目录下,好像txt,视频,音乐的话是不用考虑驱动都可以的,当然有驱动这几种文件的拷贝也会是更方便的。)
首先驱动也是分厂商和机型的(当然好像是有万能驱动这个东西的,但是我测试过万能驱动不是完全适合所有手机的),那么说到厂商和机型,应该就会想到VID 和PID了,前面说过VID代表厂商PID代表型号。 那么就知道用什么来匹配驱动了,当然说到匹配的话就说明驱动有很多,虽然有些厂商的所有机型或者某一系列的机型是使用同一个驱动就行了,但是也有很多例外 的(这就说明,自己弄一个仿91助手的东西还是做来自己玩玩的,要做成商业软件的话你还得去收集驱动呢。)
主要是用到UpdateDriverForPlugAndPlayDevices(HWND hwndParent,LPCWSTR HardwareId,LPCWSTR FullInfPath,DWORD InstallFlags,PBOOL bRebootRequired);这 个API,不敢相信还有那么长名称的API。这个API第一个参数可以为空句柄,第二个参数是硬件ID(这个在第二节讲过,和兼容ID一起的那个),第三 个是.inf文件的全路径(就是上面第二张图里面那个),第四个参数填0就行(有需要的可以再详细研究这个参数值),第四个要传一个BOOL型的指针进去 等API返回一个是否要重启的值告诉你这个驱动安装后要真正运作起来是否要重启。
五、使用adb获取手机信息
到这里,我知道的就差不多了。后面就是跟android手机的命令传递了。这些操作主要使用到android工具包---adb(android debug bridge)。这个东西是google提供的,网上有大量的教程,使用起来很简单。
WinExec("adb -d devices",SW_HIDE); Sleep(1200);SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); char buffer[1024] = {0}; //用1K的空间来存储输出的内容,只要不是显示文件内容,一般情况下是够用了。 DWORD recvLen; DWORD occupyLen = 0;TCHAR command[1024] = _T("adb -d shell getprop ro.product.brand"); //获取厂商名称//_T("adb -d shell getprop ro.product.model") //设备型号//_T("adb -d shell getprop ro.build.version.release") //android版本//_T("adb -d shell dumpsys iphonesubinfo"} //IMEI码//_T("adb -d shell cat /sys/class/net/wlan0/address") //MAC地址 HANDLE hRead,hWrite; if (!CreatePipe(&hRead,&hWrite,&sa,0)) return 0;PROCESS_INFORMATION pi;STARTUPINFO si; si.cb = sizeof(STARTUPINFO); GetStartupInfo(&si); si.wShowWindow = SW_HIDE; si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;si.hStdError = hWrite; //把子进程的标准错误输出重定向到管道输入 si.hStdOutput = hWrite; //把子进程的标准输出重定向到管道输入 si.hStdInput = hRead; //把子进程的标准输入重定向到管道输出 TCHAR command[1024] = _T("adb -d shell getprop ro.product.brand"); //获取厂商名称if (! CreateProcess(NULL, command,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi)) // 启动进程以调用ADB { CloseHandle(hWrite); CloseHandle(hRead); return FALSE; } CloseHandle(hWrite);if(WaitForSingleObject(pi.hProcess,800) == WAIT_TIMEOUT) //800ms的处理等待时间. {TerminateProcess(pi.hProcess,WAIT_TIMEOUT);CloseHandle(pi.hProcess);return FALSE;}////if(ReadFile(hRead,buffer,200,&recvLen,NULL)) //IMEI码的要做特殊处理。 {CStringA strIMEI = buffer;if(strIMEI.Find("error:") == -1){strIMEI = strIMEI.Mid(strIMEI.FindOneOf("=")+2);strcpy_s(buffer,1024,strIMEI.GetBuffer());strIMEI.ReleaseBuffer();occupyLen=strIMEI.GetLength();}}}/// ReadFile(hRead,buffer,1024,&occupyLen,NULL); //其他信息直接返回读取到的东西就行。 buffer[occupyLen-3] = '\0';CloseHandle(hRead);CloseHandle(pi.hThread);CloseHandle(pi.hProcess);TerminateProcess(pi.hProcess,0);
回到目录
[转]仿91助手的PC与android手机通讯相关推荐
- 仿91助手的PC与android手机通讯(4) --- 自动安装手机驱动
上一节讲到检查驱动安装情况,那么如果遇到没安装手机驱动的话是没办法和手机进行通讯的(除非你是要直接把文件拷贝到手机目录下,好像txt,视频,音乐的话是不用考虑驱动都可以的,当然有驱动这几种文件的拷贝也 ...
- 仿91助手的PC与android手机通讯(1) --- 检测设备插入
知道91助手和豌豆莢吧? 说到这两个东西,最让人好奇的应该是就是和手机的交互了.我之前有研究过电脑和安卓的交互,基本功能已经走通了,在这里我想分享一下. 初初看这个问题觉得很简单,然后如果你有点计算机 ...
- 仿91助手的PC与android手机通讯(2) --- 检测是否是手机
上一篇日志说了如何响应设备插入,但是设备有很多中,多媒体设备,鼠标键盘什么的都是,那如何判断是不是USB设备或者是手机插入呢? 这里就介绍一下我自己的研究结果,当然我没有去研究过苹果设备,但是按道理是 ...
- 仿91助手的PC与android手机通讯(5) --- 使用adb获取手机信息
到这里,我知道的就差不多了.后面就是跟android手机的命令传递了.这些操作主要使用到android工具包---adb(android debug bridge).这个东西是google提供的,网上 ...
- 您可以在Windows PC或Android手机上使用iMessage吗?
Denys Prykhodov/Shutterstock.comDenys Prykhodov / Shutterstock.com Want iMessage for Android or Wind ...
- 从 PC 解锁 Android 手机的 6 种有效方法
在这个数字时代,手机已成为我们生活的重要组成部分.我们将它们用于各种用途,从跟踪我们的工作和社交日程到与亲人交流. 然而,有时我们的手机会成为令人沮丧的源头,尤其是当我们不小心将自己拒之门外时.但是您 ...
- windows读取android手机内容,Win10 PC到Android手机共享内容的技巧
最近推出的Your Phone应用程序在很短的时间内在Windows 10用户中获得了极大的欢迎.用户可以直接使用他们的桌面访问存储在手机内存中的消息和照片.好消息是,您现在可以将Windows 10 ...
- PC 远程控制 android手机的方法之一VNC
1.VNC访问 a .在android手机中安装vnc 的服务端:androidvncserver http://code.google.com/p/android-vnc-server/ 本文下载了 ...
- airdrop 是 蓝牙吗_您可以在Windows PC或Android手机上使用AirDrop吗?
airdrop 是 蓝牙吗 Aleksey Khilko/Shutterstock.comAleksey Khilko / Shutterstock.com Apple's AirDrop is a ...
最新文章
- Python实例浅谈之三Python与C/C++相互调用
- mysql 事务 锁 并发
- KDD 18论文解读 | 斯坦福大学提出全新网络嵌入方法 — GraphWave
- Qt学习笔记之网络和连接
- RGB与YUV相互转换
- TQ210 —— s5pv210 Linux内核结构
- 最近自学 Asp.net MVC 小总结
- 无限网盘,36个T,360网盘无限空间的申请方法www.credream.com
- 深入浅出Symfony2 - 结合MongoDB开发LBS应用
- 云主机管理系统源码php,云优CMS PHP企业网站管理系统(分站版) v2.0.8
- Web前端第三季(JavaScript):十二:第4章: 表单校验案例:401-开发注册表单页面+402-表单提交事件和获取html元素+403-完成用户名和邮箱的校验
- 微信小程序 tab点击切换(不滑动)
- 计算机类普刊有哪些,计算机类普刊期刊发表推荐
- Windows 7精简版(2019.04.10)
- Python爬取pilipili排行榜
- ubuntu使用记录(3)ubuntu 防火墙开放端口(开启ssh)
- 3D和IMAX 3D带你体验加勒比的惊涛怪浪
- iView框架Select组件
- KEIL 调试的 ini 文件有什么用?
- thunderbird(雷鸟)企业邮件每次启动重复收到同一份邮件解决方法