[转]仿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);
不是固定的,好像是跟手机的硬件有关,但是同一款手机型号是一样的,有些品牌如vivo是一个系列都基本一样的硬件ID,甚至现在市面上的很多山寨手机直
接就是用HTC的一个硬件ID(哈哈,那时候我去手机店采集硬件ID的时候就感概现在的山寨不硬件识别的ID都直接copy了,这个可能是商业问题,我也
不懂.)
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你,你安装一下",然后你的手机就装上去了,那不就方便了吗? 这才是卖点~
"实例ID" ,这个和"兼容ID"、"硬件ID"不一样,前者是电脑给设备分配的ID便于电脑对I/O设备的管理,而后两者是设备本身的属性信息。
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,视频,音乐的话是不用考虑驱动都可以的,当然有驱动这几种文件的拷贝也会是更方便的。)
和PID了,前面说过VID代表厂商PID代表型号。
那么就知道用什么来匹配驱动了,当然说到匹配的话就说明驱动有很多,虽然有些厂商的所有机型或者某一系列的机型是使用同一个驱动就行了,但是也有很多例外
的(这就说明,自己弄一个仿91助手的东西还是做来自己玩玩的,要做成商业软件的话你还得去收集驱动呢。)
这些方法都很蛋疼的,你自己去实践一下就知道了,除非有专门人员帮你收集,否则真的很蛋疼。而我以前的收集驱动的方法就是用豌豆荚插手机,然后豌豆荚会
在C盘的临时文件夹中存放该VID/PID对应的驱动准备安装,然后拷贝下来(-
-),等驱动安装完成豌豆荚会把驱动文件删除,所以你要在豌豆荚询问“是否安装驱动”的时候别确定也别取消,然后去拷贝驱动吧,这里你可能需要用到一个辅
助软件(Everything)帮你定位这个临时文件夹,这个是一个本地文件搜索软件,搜索速度别拿windows的来比,因为windows那个根本没
法比,那个快是瞬间~~~,十分high。
----------想到就心酸的操作。
认”“下一步”的东西,但是这个我们无法控制,用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();
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
char buffer[] = {}; //用1K的空间来存储输出的内容,只要不是显示文件内容,一般情况下是够用了。
DWORD recvLen;
DWORD occupyLen = ;
TCHAR command[] = _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,))
return ;
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[] = _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,) == WAIT_TIMEOUT) //800ms的处理等待时间.
{
TerminateProcess(pi.hProcess,WAIT_TIMEOUT);
CloseHandle(pi.hProcess);
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if(ReadFile(hRead,buffer,,&recvLen,NULL)) //IMEI码的要做特殊处理。
{
CStringA strIMEI = buffer;
if(strIMEI.Find("error:") == -)
{
strIMEI = strIMEI.Mid(strIMEI.FindOneOf("=")+);
strcpy_s(buffer,,strIMEI.GetBuffer());
strIMEI.ReleaseBuffer();
occupyLen=strIMEI.GetLength();}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ReadFile(hRead,buffer,,&occupyLen,NULL); //其他信息直接返回读取到的东西就行。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
buffer[occupyLen-] = '\0';
CloseHandle(hRead);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
TerminateProcess(pi.hProcess,);
[转]仿91助手的PC与android手机通讯的更多相关文章
- 简单实现Android手机“全局可调试”(ro.debuggable = 1)的方法【锤子坚果3】
在Android真机上调试程序有一个前提,就是这个apk包必须有 debuggable=true 的属性才行.而除了自己开发的apk能够控制打包属性之外,其他的程序发行之后显然不会设这个值为 true ...
- ORB-SLAM2 运行 —— ROS + Android 手机摄像头
转载请注明出处,谢谢 原创作者:Mingrui 原创链接:https://www.cnblogs.com/MingruiYu/p/12404730.html 本文要点: ROS 配置安装 解决 sud ...
- 借助91助手,将ibook中的pdf文件拷贝至其它的pdf阅读器中(ios设备无需越狱)
有时候在使用ios自带的ibook阅读pdf文件的时候,会发现ibook有些功能并不是那么方便.最近我就遇到了一例,我想在ibook中放一本比较大的pdf书,页数有几百吧,pdf文件本身每一章节都是有 ...
- Droid@screen:在PC屏幕上显示Android手机屏幕
这里介绍一款工具——Droid@screen,用来获取手机屏幕,显示在PC屏幕上.它集截图.录像等多种功能于一体. 安装 1. 下载地址:http://droid-at-screen.org/d ...
- android手机连接PC无法正常安装驱动
工作当中我们经常会遇到Android手机连接PC的时候无法正确安装驱动,或者安装失败.当然找到正确的驱动文件时首选的解决方案,如果正确的驱动文件依旧无法安装成功我们可以打开我的电脑-->属性-- ...
- 网络编程之PC版与Android手机版带断点续传的多线程下载
一.多线程下载 多线程下载就是抢占服务器资源 原理:服务器CPU 分配给每条线程的时间片相同,服务器带宽平均分配给每条线程,所以客户端开启的线程越多,就能抢占到更多的服 ...
- system CPU占用率过高与91助手的关系
今天正在认真工作,忽然发现电脑越来越慢. 按 CTRL+ALT+DEL打开任务管理器看了下CPU使用率.其中system占用率居然达到了64%.不对劲儿,按照平时习惯,system根本占用了不要这么多 ...
- HTML5网页录音和上传到服务器,支持PC、Android,支持IOS微信
准备做一个网页版聊天界面,表情啊.图片啊.上传文件啊都应该要有,视频就算了,语音还是要的. 本文记录的是在网页上用GitHub上的Recorder进行在线录音和上传到服务器,前几天升了一下级,以后有时 ...
- [Android] Android 手机下 仿 微信 客户端 界面 -- 微聊
Android 手机下 仿 微信 客户端 界面 -- 微聊 (包括聊天列表 + 聊天对话页 + 朋友圈列表页 + 我的/发现 列表页) 项目演示: 功能说明: 1)底部标签切换 (TabHost + ...
随机推荐
- Android开发(二)——自定义圆形控件的使用CircleImageView
CircleImageView,a fast circular ImageView perfect for profile images. 主要的类CircleImageView: package d ...
- 为python 添加新功能-dump
一直觉得thinkphp提供的dump函数挺好用的,但是python里面没有,就一直想着写个简单的. dir是我比较常用的一个内置函数了,但是显示效果实在有点受不了,每次我都要从大量的字符串里找到我需 ...
- 用eclipse调试scala工程代码
1,在scala工程下面执行命令:sbt -jvm-debug 9999 2,然后执行命令:run,程序就跑起来了 3,然后用eclipse工具导入scala工程. 4,最后配置调试信息,端口号跟上面 ...
- 1. 决策树(Decision Tree)-决策树原理
1. 决策树(Decision Tree)-决策树原理 2. 决策树(Decision Tree)-ID3.C4.5.CART比较 1. 前言 决策树是一种基本的分类和回归方法.决策树呈树形结构,在分 ...
- 纯CSS3打造非常炫的加载动画
纯css3打造的一款非常炫的加载图.用在需要一定时间加载的地方非常合适.先上效果图: 点击这里在线预览 代码非常简单.没有用任何javascript代码.纯css3实现. html代码: <di ...
- C语言 · 最长单词
算法提高 最长单词 时间限制:1.0s 内存限制:512.0MB 编写一个函数,输入一行字符,将此字符串中最长的单词输出. 输入仅一行,多个单词,每个单词间用一个空格隔开.单词仅由小 ...
- Pycharm新建文件时自动添加基础信息
位置:File->settings->Editor->File and Code Templates->Python Script 添加以下代码: #!/usr/bin/env ...
- SpringBoot 集成 Mybatis 使用 Druid数据源 MySQL数据库
思路: 1.创建项目 项目结构如下: 2.导入相应包 POM.xml文件如下: <?xml version="1.0" encoding="UTF-8"? ...
- AD集成库元件简写中英文对照表
序号 英文简写 元件英文名 元件中文名 1 Res semi Semiconductor Resistor 半导体电阻 2 Cap semi Semiconductor Capacitor 半导体电容 ...
- ps 和 grep 查找消除 grep自身查找
用ps -def | grep查找进程很方便,最后一行总是会grep自己. $ ps -def | grep dragonfly-framework dean 5273 5272 0 15:23 pt ...