コード例 #1
0
        /// <summary>
        /// 拷贝文件到设备
        /// localFile:本地文件
        /// remoutFile:设备存储文件路径
        /// </summary>
        private bool DoPushFile(Device device, string localFile, string remoutFile,
                                int bufferSize = 64 * 1024,
                                int maxtimeout = 9000)
        {
            FileStream fs = null;

            byte[] remoutFileBytes = Encoding.UTF8.GetBytes(remoutFile);
            fs = new FileStream(localFile, FileMode.Open, FileAccess.Read);
            //socket
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                socket.Connect(this.SocketAddress);
                socket.ReceiveTimeout    = maxtimeout;
                socket.SendTimeout       = maxtimeout;
                socket.Blocking          = true;
                socket.ReceiveBufferSize = bufferSize;
                this.SetDevice(socket, device);
                this.SendAsyncReqest(socket);
                var request =
                    AdbSocketHelper.CreateSendFileRequest(
                        Encoding.UTF8.GetBytes("SEND"), remoutFileBytes);
                AdbSocketHelper.Write(socket, request);
                //send data
                var buf   = new byte[bufferSize + 8];
                var cdata = Encoding.UTF8.GetBytes("DATA");
                Array.Copy(cdata, 0, buf, 0, cdata.Length);
                int readindex = 1;
                while (readindex > 0)
                {
                    readindex = fs.Read(buf, 8, bufferSize);
                    readindex.Swap32bitsToArray(buf, 4);
                    AdbSocketHelper.Write(socket, buf, readindex + 8);
                }
                // create the DONE message
                long time = 1447655524;
                var  msg  = AdbSocketHelper.CreateRequest(Encoding.UTF8.GetBytes("DONE"),
                                                          (int)time);
                AdbSocketHelper.Write(socket, msg);
                var result = new byte[8];
                AdbSocketHelper.Read(socket, result);
                if (!AdbSocketHelper.CheckResult(result, Encoding.UTF8.GetBytes("OKEY")))
                {
                    throw new Exception("Push file:RESULT_UNKNOWN_ERROR");
                }
                return(true);
            }
            catch (Exception ex)
            {
            }
            finally
            {
                fs.Dispose();
                this.DisposeSocket(socket);
            }
            return(false);
        }
コード例 #2
0
        /// <summary>
        /// 执行文件拷贝钱,发生异步通知,测试
        /// </summary>
        /// <param name="socket"></param>
        private void SendAsyncReqest(Socket socket)
        {
            byte[] request = AdbSocketHelper.FormAdbRequest("sync:");
            AdbSocketHelper.Write(socket, request);
            var res = AdbSocketHelper.ReadResponse(socket);

            if (!res.IsOkay)
            {
                throw new ApplicationException("socket response error:" + res.Data);
            }
        }
コード例 #3
0
        /// <summary>
        /// 查找当前设备列表 如果返回null 说明adb连接失败
        /// </summary>
        /// <returns>如果返回null 说明adb连接失败</returns>
        private List <Device> FindCurConnectDevices()
        {
            List <Device> result = new List <Device>();

            using (AdbSocketOperator _androidManagementSocket = new AdbSocketOperator())
            {
                if (!_androidManagementSocket.IsOpened)
                {
                    return(null);
                }
                try
                {
                    var request = AdbSocketHelper.CmdToBytes("host:devices");
                    _androidManagementSocket.Write(request);
                    var res = _androidManagementSocket.ReadResponse();
                    if (res.IsOkay)
                    {
                        var len  = _androidManagementSocket.ReadDataLength(4);
                        var data = new byte[len];
                        _androidManagementSocket.Read(data);
                        string devString = Encoding.UTF8.GetString(data);

                        if (!string.IsNullOrWhiteSpace(devString))
                        {
                            string[] devices = devString.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
                            Regex    re      = new Regex(Re_DeviceList_Info, RegexOptions.Compiled | RegexOptions.IgnoreCase);
                            foreach (var ds in devices)
                            {
                                Match m = re.Match(ds);
                                if (!m.Success)
                                {
                                    LoggerManagerSingle.Instance.Error(string.Format("无法识别的设备信息:{0}", ds));
                                    continue;
                                }
                                Device d  = new Device(m.Groups[1].Value);
                                var    st = m.Groups[2].Value;
                                //找到的设备都为在线状态
                                if (st == "device")
                                {
                                    d.Status = EnumDeviceStatus.Online;
                                    result.Add(d);
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    LoggerManagerSingle.Instance.Error(e);
                }
            }

            return(result);
        }
コード例 #4
0
        /// <summary>
        /// 执行shell命令,返回string
        /// </summary>
        /// <param name="command"></param>
        /// <param name="device"></param>
        /// <param name="receiver"></param>
        /// <param name="buffersize"></param>
        /// <param name="maxtimeout"></param>
        /// <returns></returns>
        ///
        private string ExecuteRemoteCommandString(string command, Device device,
                                                  AbstractOutputReceiver receiver,
                                                  int buffersize = 16 * 1024,
                                                  int maxtimeout = 3000)
        {
            if (String.IsNullOrWhiteSpace(command) || device == null)
            {
                throw new ArgumentException("The command or device is invalid");
            }
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                socket.Connect(this.SocketAddress);
                socket.ReceiveTimeout    = maxtimeout;
                socket.SendTimeout       = maxtimeout;
                socket.ReceiveBufferSize = buffersize;
                this.SetDevice(socket, device);
                //reqest
                var request = AdbSocketHelper.FormAdbRequest("shell:" + command);
                AdbSocketHelper.Write(socket, request);
                //response
                var res = AdbSocketHelper.ReadResponse(socket);
                if (!res.IsOkay)
                {
                    throw new ApplicationException(string.Format("device[{0}] response error:{1}", device.SerialNumber, res.Data));
                }
                //read
                AdbSocketHelper.Read(socket, receiver, buffersize);
                //验证输出是否合法
                //determines weahter the output is valid
                var tdata = receiver.Data.ToString().Trim();

                return(tdata);
            }
            catch (DoneWithReadException de)
            {
            }
            catch (SocketException ex)
            {
                throw new ApplicationException(string.Format("The shell command\"{0} \" has become unresponsive! ,max timeout:{1}", command, maxtimeout));
            }
            finally
            {
                this.DisposeSocket(socket);
            }

            return(string.Empty);
        }
コード例 #5
0
        /// <summary>
        /// 设置当前使用的设备
        /// Sets the device.
        /// </summary>
        private void SetDevice(Socket adbChan, Device device)
        {
            String msg = "host:transport:" + device.SerialNumber;

            byte[] device_query = AdbSocketHelper.FormAdbRequest(msg);
            AdbSocketHelper.Write(adbChan, device_query);
            var res = AdbSocketHelper.ReadResponse(adbChan);

            if (!res.IsOkay)
            {
                if (String.Compare("device not found", res.Data, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    throw new ApplicationException(string.Format("I'm so sorry,device[{0}] not found", device.SerialNumber));
                }
                else
                {
                    throw new ApplicationException("device (" + device + ") request rejected: " + res.Data);
                }
            }
        }
コード例 #6
0
        /// <summary>
        /// 执行ADB指令,可以指定端口,device可以为null,若为null则不指定设备。
        /// 结果接收器receiver可以为null,为null则不处理结果数据
        /// </summary>
        public void ExecuteAdbSocketCommand(Device device, string command, int port = 5037,
                                            AbstractOutputReceiver receiver         = null,
                                            int bufSize = 16 * 1024, int timeOut = 9000)
        {
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                socket.Connect(IPAddress.Loopback, port);
                socket.Blocking          = true;
                socket.ReceiveBufferSize = bufSize;
                socket.SendBufferSize    = bufSize;
                socket.ReceiveTimeout    = timeOut;
                socket.SendTimeout       = timeOut;
                if (device != null)
                {
                    this.SetDevice(socket, device);
                }
                byte[] request = AdbSocketHelper.FormAdbRequest(command);
                AdbSocketHelper.Write(socket, request);
                var res = AdbSocketHelper.ReadResponse(socket);
                if (!res.IsOkay)
                {
                    throw new Exception(string.Format("Device rejected command:{0}. Error:{1} ", command, res.Data));
                }

                if (receiver != null)
                {
                    AdbSocketHelper.Read(socket, receiver, bufSize);
                }
            }
            finally
            {
                this.DisposeSocket(socket);
            }
        }
コード例 #7
0
        /// <summary>
        /// 判断文件或者路径是否存在
        /// </summary>
        /// <param name="device"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        private bool IsExistsFileOrPath(Device device, string path)
        {
            int             buffersize = 16 * 1024;
            int             maxtimeout = 9000;
            DefaultReceiver receiver   = new DefaultReceiver();

            string command = string.Format("ls -l {0}", path.TrimEnd(new char[] { '#', 'F' }));

            if (device.IsRoot)
            {
                command = string.Format("su -c \"{0}\" ", command);
            }

            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                socket.Connect(this.SocketAddress);
                socket.ReceiveTimeout    = maxtimeout;
                socket.SendTimeout       = maxtimeout;
                socket.ReceiveBufferSize = buffersize;

                //设置当前使用设备
                String msg          = "host:transport:" + device.SerialNumber;
                byte[] device_query = AdbSocketHelper.FormAdbRequest(msg);
                AdbSocketHelper.Write(socket, device_query);
                var res = AdbSocketHelper.ReadResponse(socket);
                if (!res.IsOkay)
                {
                    return(false);
                }

                //reqest
                var request = AdbSocketHelper.FormAdbRequest("shell:" + command);
                AdbSocketHelper.Write(socket, request);
                //response
                res = AdbSocketHelper.ReadResponse(socket);
                if (!res.IsOkay)
                {
                    return(false);
                }
                //read
                AdbSocketHelper.Read(socket, receiver, buffersize);
                //验证输出是否合法
                //determines weahter the output is valid
                string[] cmd   = command.Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                var      tdata = receiver.Data.ToString().Trim();
                if (tdata.Contains(String.Format("{0}: not found", cmd[0])))
                {
                    return(false);
                }
                if (tdata.Contains("No such file or directory"))
                {
                    return(false);
                }
                if (tdata.Contains("no closing quote"))
                {
                    return(false);
                }
            }
            finally
            {
                this.DisposeSocket(socket);
            }

            return(true);
        }
コード例 #8
0
        /// <summary>
        /// 执行SPF app指令,并返回结果。
        /// </summary>
        /// <returns></returns>
        public string ExecuteSPFAppCommand(Device device, string command = "basic_info", int timeout = 12000)
        {
            // 服务启动提取失败:是否进行过重试
            int doretry = 0;

DoRetry:

            var port = _ForwardProt++;
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                /**
                 * 启动APP:
                 * 目前APP支持两种启动方式,一种为服务命令,一种为直接启动组件
                 * 服务启动方式:优点是用户不需要做任何操作,缺点是启动服务不稳定,针对部分手机启动受权限限制
                 * 组件启动方式:优点是启动服务稳定,缺点是启动组件时屏幕会闪动一下,用户体验比较差
                 * 综合上述两种启动方式,在APP中提供两种启动方式,有限已服务启动,启动失败后再通过组件方式进行启动
                 */
                // 服务启动
                if (!AppServiceStart(device, port, 12345) || doretry == 1 || doretry == 2)
                {
                    // 组件启动
                    AppAmStart(device, port, 12345);
                }

                socket.Connect(IPAddress.Loopback, port);
                socket.Blocking          = true;
                socket.ReceiveBufferSize = 16 * 1024;
                socket.SendBufferSize    = 16 * 1024;
                socket.ReceiveTimeout    = timeout;
                socket.SendTimeout       = timeout;
                byte[] request = Encoding.UTF8.GetBytes(command);
                AdbSocketHelper.Write(socket, request);
                var res = AdbSocketHelper.ReadResponse(socket);
                if (!res.IsOkay)
                {
                    // 服务启动提取数据失败后则转变为组件方式启动提取数据
                    if (doretry == 0)
                    {
                        doretry = 1;
                        goto DoRetry;
                    }
                    else
                    {
                        throw new Exception(string.Format("Device rejected command:{0}. Error:{1} ", command, res.Data));
                    }
                }
                var sizebuf = new byte[16];
                socket.Receive(sizebuf);
                int length  = Convert.ToInt32(sizebuf.GetString(Encoding.UTF8), 16);
                var databuf = new byte[length];
                socket.ReceiveBufferSize = length;
                AdbSocketHelper.Read(socket, databuf, length);
                return(databuf.GetString(Encoding.UTF8));
            }
            catch (Exception ex)
            {
                if (doretry <= 1)
                {
                    doretry = 2;
                    goto DoRetry;
                }
                else
                {
                    throw new Exception("ReceiveSPFAppData Error,", ex);
                }
            }
            finally
            {
                this.DisposeSocket(socket);
                //remove forward
                try
                {
                    var sc2 = String.Format("host-serial:{0}:killforward-all", device.SerialNumber);
                    this.ExecuteAdbSocketCommand(null, sc2);
                }
                catch { }
            }
        }
コード例 #9
0
        /// <summary>
        /// 执行文件拷贝到本地操作
        /// </summary>
        private void DoPullFile(Device device, string sourceFile, string local, PullFileReceiver receiver = null,
                                int bufferSize = 64 * 1024,
                                int maxtimeout = 9000, bool trycat = true)
        {
            if (device == null || String.IsNullOrWhiteSpace(sourceFile) || String.IsNullOrWhiteSpace(local))
            {
                return;
            }

            #region /data/data/文件处理

            //只处理/data/data/文件夹下文件
            bool   IsNeedMoveFile = sourceFile.Replace('\\', '/').StartsWith("/data/data/") && sourceFile.EndsWith(".db");
            var    dr             = new DefaultReceiver();
            string rmCmd          = "";

            if (IsNeedMoveFile)
            {
                string tempSrc = string.Format("/data/local/tmp/{0}", FileHelper.GetFileName(local));
                string cpCmd   = string.Format("cp {0} /data/local/tmp", sourceFile);

                this.ExecuteRemoteAutoCommandNoException(cpCmd, device, dr); //拷贝/data/data/ 到/data/local/tmp

                if (this.IsExistsFileOrPath(device, tempSrc))                //判断是否拷贝成功
                {
                    this.UpgradeFilePermission(device, tempSrc);             //提权
                    sourceFile = tempSrc;
                    rmCmd      = string.Format("rm {0}", tempSrc);
                }
            }

            #endregion

            receiver = receiver ?? new PullFileReceiver(local);

            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                socket.Connect(this.SocketAddress);
                socket.ReceiveTimeout    = maxtimeout;
                socket.SendTimeout       = maxtimeout;
                socket.Blocking          = true;
                socket.ReceiveBufferSize = bufferSize;
                this.SetDevice(socket, device);
                this.SendAsyncReqest(socket);
                var request = AdbSocketHelper.FormPullFileRequest(sourceFile);
                AdbSocketHelper.Write(socket, request);
                receiver.DoReceive(socket);
            }
            catch (ADBConnectionException cex)
            {
                var mes = string.Format("pull file[{0}] failed:{1}", sourceFile, cex.Message);

                if (trycat)
                {
                    var rec = new CatToFileReceiver(local);
                    rec.OnReceiveData = receiver.OnReceiveData;
                    var rt = this.CatToFile(device, sourceFile, local, rec);
                    if (rt != string.Empty)
                    {
                        throw new Exception(rt);
                    }
                }
                else
                {
                    throw new ApplicationException(mes, cex);
                }
            }
            catch (Exception ex)
            {
                throw new ApplicationException(string.Format("pull file[{0}] failed", sourceFile), ex);
            }
            finally
            {
                if (IsNeedMoveFile && !String.IsNullOrWhiteSpace(rmCmd))
                {//删除temp文件
                    try
                    {
                        this.ExecuteRemoteAutoCommandNoException(rmCmd, device, dr);
                    }
                    catch { }
                }

                this.DisposeSocket(socket);
            }
        }