예제 #1
0
        /// <summary>
        /// APP服务启动
        /// 目前APP支持两种启动方式,一种为服务命令,一种为直接启动组件
        /// 服务启动方式:优点是用户不需要做任何操作,缺点是启动服务不稳定,针对部分手机启动受权限限制</summary>
        /// 组件启动方式:优点是启动服务稳定,缺点是启动组件时屏幕会闪动一下,用户体验比较差<param name="device">设备对象</param>
        /// 综合上述两种启动方式,在APP中提供两种启动方式,有限已服务启动,启动失败后再通过组件方式进行启动<param name="port">映射端口(第一个:“12580”是由你们自己定义的pc端口,第二个你们不用管,它是手机端的服务端口)</param>
        /// <param name="tcp">默认密码</param>
        /// <returns>是否成功,true成功,反之亦然</returns>
        private bool AppServiceStart(Device device, int port, int tcp = 12345)
        {
            try
            {
                DefaultReceiver dreceiver = new DefaultReceiver();
                string          sc1       = "am startservice -n mwh.com.spfsocket/mwh.com.spfsocket.MainService";
                this.ExecuteRemoteCommand(sc1, device, dreceiver);
                if (device.IsRoot)
                {
                    sc1 = "su -c \"am startservice -n mwh.com.spfsocket/mwh.com.spfsocket.MainService\"";
                    this.ExecuteRemoteCommand(sc1, device, dreceiver);
                }
                string sc2 = String.Format("host-serial:{0}:forward:tcp:{1};tcp:{2}", device.SerialNumber, port, tcp);
                this.ExecuteAdbSocketCommand(null, sc2);

                // 服务启动失败则使用组件启动
                if (dreceiver.Lines.Contains("Error: Not found; no service started."))
                {
                    return(false);
                }
                return(true);
            }
            catch (Exception ex)
            {
                // 组件启动
                if (AppAmStart(device, port, 12345))
                {
                    return(true);
                }
                return(false);
            }
        }
예제 #2
0
        /// <summary>
        /// 拷贝本地文件到设备临时目录(/data/local/tmp/)
        /// </summary>
        public string PushSingleFile(Device device, string localFile, string remotePath,
                                     int bufferSize = 64 * 1024,
                                     int maxtimeout = 9000)
        {
            if (!System.IO.File.Exists(localFile))
            {
                return(string.Empty);
            }
            //验证目标目录
            if (!this.RemoutFileIsExist(device, remotePath))
            {
                DefaultReceiver reciver = new DefaultReceiver();
                this.ExecuteRemoteAutoCommand(string.Format("mkdir -p {0}", remotePath), device, reciver);
            }
            this.UpgradeFilePermission(device, remotePath);

            var remoutFile = ConnectLinuxPath(remotePath, Path.GetFileName(localFile));

            try
            {
                if (this.DoPushFile(device, localFile, remoutFile, bufferSize, maxtimeout))
                {
                    return(remoutFile);
                }
            }
            catch (Exception ex)
            {
            }
            return(string.Empty);
        }
예제 #3
0
 /// <summary>
 /// 卸载指定包名的App,如com.mwh.spfsocket
 /// </summary>
 /// <param name="packageName"></param>
 public void UninstallPackage(string packageName, Device device)
 {
     try
     {
         var             cmd      = string.Format("pm uninstall {0}", packageName);
         DefaultReceiver receiver = new DefaultReceiver();
         this.ExecuteRemoteCommand(cmd, device, receiver);
     }
     catch (Exception ex)
     {
     }
 }
예제 #4
0
 /// <summary>
 /// 验证一个目录或文件是已存在
 /// </summary>
 /// <param name="device"></param>
 /// <param name="remouteFile"></param>
 internal bool RemoutFileIsExist(Device device, string remouteFile)
 {
     try
     {
         DefaultReceiver receiver = new DefaultReceiver();
         //若文件名中包含空格
         var path = remouteFile.Replace(" ", "\\ ");
         this.ExecuteRemoteAutoCommand(string.Format("ls -l {0}", path), device, receiver);
         return(true);
     }
     catch (FileNotFoundException ex)
     {
         return(false);
     }
 }
예제 #5
0
        /// <summary>
        /// 安装本地制定apk文件到手机,强制安装。
        /// 默认安装到data/local/tmp/
        /// </summary>
        public bool InstallPackage(string localFile, Device device, string remoutePath = "/data/local/tmp/")
        {
            string remouteFile = string.Empty;
            var    flag        = false;

            try
            {
                remouteFile = this.PushSingleFile(device, localFile, remoutePath);
                if (String.IsNullOrWhiteSpace(remouteFile))
                {
                    return(false);
                }
                //1.1 要提升文件权限,这要命,找了半天才知道是这个问题
                this.UpgradeFilePermission(device, remouteFile);
                //2.install
                var             cmd      = string.Format("pm install -r {0}", remouteFile);
                DefaultReceiver receiver = new DefaultReceiver();
                this.ExecuteRemoteCommand("pm setInstallLocation 0", device, receiver);
                this.ExecuteRemoteCommand(cmd, device, receiver, 16 * 1024, 20000);
                if (Contains(receiver.Data, "success", StringComparison.OrdinalIgnoreCase))
                {
                    flag = true;
                }
                else
                {
                    throw new ApplicationException(receiver.Data);
                }
            }
            catch (Exception ex)
            {
                flag = false;
                //如果默认路径安装失败,则尝试拷贝到SDCard安装
                if (remoutePath.Equals("/data/local/tmp/"))
                {
                    flag = this.InstallPackage(localFile, device, remoutePath = this.TryParseSDCardByDict(device));
                }
            }
            finally
            {
                try
                {
                    var receiver = new DefaultReceiver();
                    this.ExecuteRemoteCommand(string.Format("rm {0}", remouteFile), device, receiver);
                }
                catch { }
            }
            return(flag);
        }
예제 #6
0
 /// <summary>
 /// 通过路径字典尝试获取SDCard路径
 /// </summary>
 private string TryParseSDCardByDict(Device device)
 {
     foreach (var p in SDCardPathDictionary)
     {
         DefaultReceiver receiver = new DefaultReceiver();
         try
         {
             this.ExecuteRemoteCommand(string.Format("ls -l {0}", p), device, receiver);
         }
         catch { continue; }
         if (receiver.Lines != null)
         {
             return(p);
         }
     }
     return(string.Empty);
 }
예제 #7
0
 /// <summary>
 /// APP组件启动
 /// </summary>
 /// <param name="device">设备对象</param>
 /// <param name="port">映射端口(第一个:“12580”是由你们自己定义的pc端口,第二个你们不用管,它是手机端的服务端口)</param>
 /// <param name="tcp">默认密码</param>
 /// <returns>是否成功,true成功,反之亦然</returns>
 private bool AppAmStart(Device device, int port, int tcp = 12345)
 {
     try
     {
         DefaultReceiver dreceiver = new DefaultReceiver();
         string          sc1       = "am start mwh.com.spfsocket/.MainActivity";
         string          sc2       = "am broadcast -a NotifyServiceStop";
         var             sc3       = String.Format("host-serial:{0}:forward:tcp:{1};tcp:{2}", device.SerialNumber, port, tcp);
         var             sc4       = "am broadcast -a NotifyServiceStart";
         this.ExecuteRemoteCommand(sc1, device, dreceiver);
         this.ExecuteRemoteCommand(sc2, device, dreceiver);
         this.ExecuteAdbSocketCommand(null, sc3);
         this.ExecuteRemoteCommand(sc4, device, dreceiver);
         return(true);
     }
     catch (Exception ex)
     {
         return(false);
     }
 }
예제 #8
0
 /// <summary>
 /// 提升文件操作权限
 /// recursion=true 支持递归所有子文件、文件夹,但有些手机(三星)不支持该参数
 /// recursion=false 只操作当前指定的文件/文件夹路径
 /// </summary>
 /// <param name="path">文件路径</param>
 public bool UpgradeFilePermission(Device device, string path, bool recursion = false)
 {
     try
     {
         //若文件名中包含空格
         path = path.Replace(" ", "\\ ");
         DefaultReceiver receiver = new DefaultReceiver();
         string          cmd      = recursion ? "chmod -R 777 {0}" : "chmod 777 {0}";
         var             result   = this.ExecuteRemoteAutoCommandNoException(string.Format(cmd, path), device, receiver);
         if (!result.Success && null != result.Ex)
         {
             return(false);
         }
         return(true);
     }
     catch (Exception ex)
     {
         return(false);
     }
 }
예제 #9
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);
        }
예제 #10
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);
            }
        }