public bool CreateForward( IPEndPoint adbSockAddr, Device device, int localPort, int remotePort ) { Socket adbChan = new Socket ( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp ); try { adbChan.Connect ( adbSockAddr ); adbChan.Blocking = true; byte[] request = FormAdbRequest ( String.Format ( "host-serial:{0}:forward:tcp:{1};tcp:{2}", //$NON-NLS-1$ device.SerialNumber, localPort, remotePort ) ); if ( !Write ( adbChan, request ) ) { throw new IOException ( "failed to submit the forward command." ); } AdbResponse resp = ReadAdbResponse ( adbChan, false /* readDiagString */); if ( !resp.IOSuccess || !resp.Okay ) { throw new IOException ( "Device rejected command: " + resp.Message ); } } finally { if ( adbChan != null ) { adbChan.Close ( ); } } return true; }
/// <summary> /// Executes a shell command on the remote device /// </summary> /// <param name="endPoint">The end point.</param> /// <param name="command">The command.</param> /// <param name="device">The device.</param> /// <param name="rcvr">The RCVR.</param> /// <param name="maxTimeToOutputResponse">The max time to output response.</param> public void ExecuteRemoteRootCommand( IPEndPoint endPoint, String command, Device device, IShellOutputReceiver rcvr, int maxTimeToOutputResponse ) { ExecuteRemoteCommand ( endPoint, String.Format ( "su -c \"{0}\"", command ), device, rcvr ); }
public void Reboot( String into, IPEndPoint adbSockAddr, Device device ) { byte[] request; if ( into == null ) { request = FormAdbRequest ( "reboot:" ); //$NON-NLS-1$ } else { request = FormAdbRequest ( "reboot:" + into ); //$NON-NLS-1$ } Socket adbChan = new Socket ( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp ); try { adbChan.Connect ( adbSockAddr ); adbChan.Blocking = true; // if the device is not -1, then we first tell adb we're looking to talk // to a specific device SetDevice ( adbChan, device ); if ( !Write ( adbChan, request ) ) { throw new IOException ( "failed asking for reboot" ); } } finally { if ( adbChan != null ) { adbChan.Close ( ); } } }
/// <summary> /// Executes a shell command on the remote device /// </summary> /// <param name="endPoint">The socket end point</param> /// <param name="command">The command to execute</param> /// <param name="device">The device to execute on</param> /// <param name="rcvr">The shell output receiver</param> /// <exception cref="FileNotFoundException">Throws if the result is 'command': not found</exception> /// <exception cref="IOException">Throws if there is a problem reading / writing to the socket</exception> /// <exception cref="OperationCanceledException">Throws if the execution was canceled</exception> /// <exception cref="EndOfStreamException">Throws if the Socket.Receice ever returns -1</exception> public void ExecuteRemoteCommand( IPEndPoint endPoint, String command, Device device, IShellOutputReceiver rcvr ) { ExecuteRemoteCommand ( endPoint, command, device, rcvr, int.MaxValue ); }
/// <summary> /// Executes a shell command on the remote device /// </summary> /// <param name="endPoint">The end point.</param> /// <param name="command">The command.</param> /// <param name="device">The device.</param> /// <param name="rcvr">The RCVR.</param> /// <remarks>Should check if you CanSU before calling this.</remarks> public void ExecuteRemoteRootCommand( IPEndPoint endPoint, String command, Device device, IShellOutputReceiver rcvr ) { ExecuteRemoteRootCommand ( endPoint, String.Format ( "su -c \"{0}\"", command ), device, rcvr, int.MaxValue ); }
/// <summary> /// Executes the remote command. /// </summary> /// <param name="endPoint">The end point.</param> /// <param name="command">The command.</param> /// <param name="device">The device.</param> /// <param name="rcvr">The RCVR.</param> /// <param name="maxTimeToOutputResponse">The max time to output response.</param> /// <exception cref="AdbException">failed submitting shell command</exception> /// <exception cref="System.OperationCanceledException"></exception> /// <exception cref="Managed.Adb.Exceptions.ShellCommandUnresponsiveException"></exception> /// <exception cref="System.IO.FileNotFoundException"></exception> /// <exception cref="UnknownOptionException"></exception> /// <exception cref="CommandAbortingException"></exception> /// <exception cref="PermissionDeniedException"></exception> public void ExecuteRemoteCommand( IPEndPoint endPoint, String command, Device device, IShellOutputReceiver rcvr, int maxTimeToOutputResponse ) { Socket socket = new Socket ( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp ); if ( !device.IsOnline ) { return; } try { socket.Connect ( endPoint ); socket.Blocking = true; SetDevice ( socket, device ); byte[] request = FormAdbRequest ( "shell:" + command ); if ( !Write ( socket, request ) ) { throw new AdbException ( "failed submitting shell command" ); } AdbResponse resp = ReadAdbResponse ( socket, false /* readDiagString */); if ( !resp.IOSuccess || !resp.Okay ) { throw new AdbException ( "sad result from adb: " + resp.Message ); } byte[] data = new byte[16384]; int timeToResponseCount = 0; while ( true ) { int count; if ( rcvr != null && rcvr.IsCancelled ) { this.LogWarn("execute: cancelled" ); throw new OperationCanceledException ( ); } count = socket.Receive ( data ); if ( count < 0 ) { // we're at the end, we flush the output rcvr.Flush ( ); this.LogInfo("execute '" + command + "' on '" + device + "' : EOF hit. Read: " + count ); break; } else if ( count == 0 ) { try { int wait = WAIT_TIME * 5; timeToResponseCount += wait; if ( maxTimeToOutputResponse > 0 && timeToResponseCount > maxTimeToOutputResponse ) { throw new AdbException ( ); } Thread.Sleep ( wait ); } catch ( ThreadInterruptedException ) { } } else { timeToResponseCount = 0; string[] cmd = command.Trim ( ).Split ( new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries ); string sdata = data.GetString ( 0, count, AdbHelper.DEFAULT_ENCODING ); var sdataTrimmed = sdata.Trim ( ); if ( sdataTrimmed.EndsWith ( String.Format ( "{0}: not found", cmd[0] ) ) ) { this.LogWarn( "The remote execution returned: '{0}: not found'", cmd[0] ); throw new FileNotFoundException ( string.Format ( "The remote execution returned: '{0}: not found'", cmd[0] ) ); } if ( sdataTrimmed.EndsWith ( "No such file or directory" ) ) { this.LogWarn ( "The remote execution returned: {0}", sdataTrimmed ); throw new FileNotFoundException ( String.Format ( "The remote execution returned: {0}", sdataTrimmed ) ); } // for "unknown options" if ( sdataTrimmed.Contains ( "Unknown option" ) ) { this.LogWarn ( "The remote execution returned: {0}", sdataTrimmed ); throw new UnknownOptionException ( sdataTrimmed ); } // for "aborting" commands if ( sdataTrimmed.IsMatch ( "Aborting.$" ) ) { this.LogWarn ( "The remote execution returned: {0}", sdataTrimmed ); throw new CommandAbortingException ( sdataTrimmed ); } // for busybox applets // cmd: applet not found if ( sdataTrimmed.IsMatch ( "applet not found$" ) && cmd.Length > 1 ) { this.LogWarn ( "The remote execution returned: '{0}'", sdataTrimmed ); throw new FileNotFoundException ( string.Format ( "The remote execution returned: '{0}'", sdataTrimmed ) ); } // checks if the permission to execute the command was denied. // workitem: 16822 if ( sdataTrimmed.IsMatch ( "(permission|access) denied$" ) ) { this.LogWarn ( "The remote execution returned: '{0}'", sdataTrimmed ); throw new PermissionDeniedException ( String.Format ( "The remote execution returned: '{0}'", sdataTrimmed ) ); } // Add the data to the receiver if ( rcvr != null ) { rcvr.AddOutput ( data, 0, count ); } } } } /*catch ( Exception e ) { Log.e ( TAG, e ); Console.Error.WriteLine ( e.ToString ( ) ); throw; }*/ finally { if ( socket != null ) { socket.Close ( ); } rcvr.Flush ( ); } }
public void RegisterDevice(Device device, DeviceListItem dli) { try { var kvp = new List<KeyValuePair<String, String>>(); var useragent = String.Format("{0}", this.GetType().Assembly.GetName().Version.ToString()); // if the Id is an IP, we need to find the real SerialNumber. var realSerialNo = device.SerialNumber; var kvpid = new KeyValuePair<string, string>("Id", realSerialNo); if(realSerialNo.Contains(":")) { // it is probably an IP:PORT combo. Lets try to get the real serial number, or what we have if we can't find it. var tid = device.Properties.FirstOrValue(x => x.Key == "ro.serialno" || x.Key == "ro.boot.serialno", new KeyValuePair<string, string>("default.serialno", realSerialNo)).Value; if(!string.IsNullOrWhiteSpace(tid) && tid != realSerialNo) { kvpid = new KeyValuePair<string, string>("Id", tid); realSerialNo = tid; } } // should we record if(!ShouldRecordStatistics(realSerialNo)) { this.LogDebug("Skipping registration of device because delay not reached."); return; } kvp.Add(kvpid); kvp.Add(new KeyValuePair<string, string>("ProductName", dli.ProductName)); kvp.Add(new KeyValuePair<string, string>("ModelName", dli.ModelName)); kvp.Add(new KeyValuePair<string, string>("DeviceName", dli.DeviceName)); device.Properties.Add("ro.droidexplorer.version", useragent); device.Properties.Add("ro.droidexplorer.root", true.ToString()); device.Properties.Add("ro.droidexplorer.busybox", true.ToString()); device.Properties.Add("ro.droidexplorer.architecture", Architecture.IsRunningX64 ? "x64" : "x86"); device.Properties.Add("ro.droidexplorer.platform", Environment.OSVersion.Platform.ToString()); device.Properties.Add("ro.droidexplorer.platformversion", Environment.OSVersion.VersionString); var propCount = 0; foreach(var item in device.Properties.Where(item => !FilteredProperties.Contains(item.Key))) { kvp.Add(new KeyValuePair<String, String>(String.Format("Properties[{0}].Name", propCount), item.Key)); kvp.Add(new KeyValuePair<String, String>(String.Format("Properties[{0}].Value", propCount), item.Value)); ++propCount; } var req = HttpWebRequest.Create(CreateUrl("device/add")) as HttpWebRequest; req.UserAgent = useragent; AddAuthenticationHeaders(req); req.ContentType = "application/x-www-form-urlencoded"; req.Method = "POST"; var data = CreateFormattedPostRequest(kvp); var bytes = data.GetBytes(); req.ContentLength = bytes.Length; req.Timeout = 60 * 1000; using(var rs = req.GetRequestStream()) { rs.Write(bytes, 0, bytes.Length); } using(var resp = req.GetResponse() as HttpWebResponse) { if(resp.StatusCode != HttpStatusCode.OK) { this.LogError(String.Format("POST Statistics Failed (Error Code: {1}): {0}", resp.StatusDescription, resp.StatusCode)); } } // track when we recorded this Settings.Instance.SystemSettings.SetLastRecordCloud(realSerialNo); } catch(WebException ex) { this.LogError(ex.Message, ex); } }
static void Main(string[] arguments) { try { using(var stream = typeof(Program).Assembly.GetManifestResourceStream(DroidExplorer.Resources.Strings.Log4NetDroidExplorer)) { XmlConfigurator.Configure(stream); } var errorMessages = new List<string>(); var args = new Arguments(arguments); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); Application.ThreadException += (sender, e) => DroidExplorer.Core.Logger.LogError(typeof(Program), e.Exception.Message, e.Exception); // show the splash dialog Program.SplashManager.ShowSplashDialog(StartUpStepCount); // load settings Logger.LogDebug ( typeof ( Program ), "Loading Droid Explorer Settings" ); Program.SplashManager.SplashDialog.SetStepText("Loading Settings..."); CommandRunner.Settings = Settings.Instance; Settings.Instance.SystemSettings = RegistrySettings.Instance; Program.SplashManager.SplashDialog.IncrementLoadStep(1); // cleanup adb? should this be done? Application.ApplicationExit += delegate(object sender, EventArgs e) { //CommandRunner.Instance.AdbProcessCleanUp ( ); }; // locate sdk tools Logger.LogDebug ( typeof ( Program ), "Locating SDK Path" ); Program.SplashManager.SplashDialog.SetStepText(DroidExplorer.Resources.Strings.SplashLocatingSdk); var sdkPath = Settings.Instance.SystemSettings.SdkPath; Logger.LogDebug ( typeof ( Program ), "SDK Path Set to {0}", sdkPath ); if ( string.IsNullOrEmpty(sdkPath)) { throw new ApplicationException("Unable to locate the android SDK tools, please reinstall the application."); } Program.SplashManager.SplashDialog.IncrementLoadStep(1); // verify the sdk tools Logger.LogDebug ( typeof ( Program ), "Verifying SDK Tools" ); Program.SplashManager.SplashDialog.SetStepText("Verifying SDK Tools"); // verify the sdk tools. var valid = FolderManagement.VerifyAndroidSdkTools (); if(!valid){ // if not valid - lets ask the user where it is. Program.SplashManager.SplashDialog.HideExt(); Logger.LogWarn( typeof ( Program ), "Unable to verify the SDK tools" ); var browser = new FolderBrowserDialog(); browser.Description = "Unable to locate SDK tools path. Please select the location where you have the Android SDK installed."; browser.ShowNewFolderButton = false; var dResult = DialogResult.OK; do { dResult = browser.ShowDialog(); if(dResult == DialogResult.OK) { Settings.Instance.SystemSettings.SdkPath = browser.SelectedPath; valid = FolderManagement.VerifyAndroidSdkTools (); } // keep asking until the user selects a valid location, or they cancel. } while(!valid && dResult == DialogResult.OK); if(!valid) { // they canceled. we are out of here. throw new ApplicationException(DroidExplorer.Resources.Strings.SdkPathNotFoundMessage); } // bring it back. Program.SplashManager.SplashDialog.AsyncShow(); } Program.SplashManager.SplashDialog.IncrementLoadStep(1); // set the sdk path CommandRunner.Instance.SdkPath = sdkPath; Program.SplashManager.SplashDialog.SetStepText(DroidExplorer.Resources.Strings.SplashStartAdb); try { // start the adb server Logger.LogDebug ( typeof ( Program ), "Starting ADB Server" ); CommandRunner.Instance.StartServer(); Program.SplashManager.SplashDialog.IncrementLoadStep(1); } catch(AdbRootException arex) { Logger.LogWarn ( typeof ( Program ), arex.Message ); } // get the attached devices Program.SplashManager.SplashDialog.SetStepText(DroidExplorer.Resources.Strings.SplashGetDevices); // BUG: 15695 // fixed this. It was because adb root was disconnecting the device and restarting it. // adb root is now called when you connect to a device. Although, it can cause the device to // not be found... another bug... Logger.LogDebug ( typeof ( Program ), "Getting connected devices" ); var devices = CommandRunner.Instance.GetDevices().ToList(); Program.SplashManager.SplashDialog.IncrementLoadStep(1); new Thread(() => { // process the devices and send them off to the cloud Logger.LogDebug ( typeof ( Program ), "Registering anonymous statistics for device types" ); CloudStatistics.Instance.RegisterModels(devices); }).Start(); // we will increment even though the process is on a new thread. Program.SplashManager.SplashDialog.IncrementLoadStep(1); // pass in the initial path? // TODO: Not yet implemented. //var initialPath = "/"; //if ( args.Contains ( "p", "path" ) && !string.IsNullOrWhiteSpace ( args["p", "path"] ) ) { // initialPath = args["p", "path"]; //} // are we attaching to a specific device? if ( args.Contains("d", "device")) { CommandRunner.Instance.DefaultDevice = args["d", "device"]; Logger.LogDebug( typeof ( Program ), DroidExplorer.Resources.Strings.SplashConnectingDevice, CommandRunner.Instance.DefaultDevice); Application.Run(new MainForm( ) ); } else { // get the attached devices String selectedDevice = null; if(devices.Count() != 1) { // we have 0 or > 1 so we need to display the "selection dialog" var dsf = new GenericDeviceSelectionForm(); Program.SplashManager.SplashDialog.HideExt(); if(dsf.ShowDialog(null) == DialogResult.OK) { CommandRunner.Instance.DefaultDevice = dsf.SelectedDevice; Logger.LogDebug ( typeof ( Program ), DroidExplorer.Resources.Strings.SplashConnectingDevice, CommandRunner.Instance.DefaultDevice ); selectedDevice = dsf.SelectedDevice; } else { Program.SplashManager.CloseSplashDialog(); return; } Program.SplashManager.SplashDialog.AsyncShow(); } else { selectedDevice = devices[0].SerialNumber; CommandRunner.Instance.DefaultDevice = selectedDevice; } // try to run adb as root: try { Program.SplashManager.SplashDialog.SetStepText(DroidExplorer.Resources.Strings.SplashRunAdbAsRoot); Logger.LogDebug ( typeof ( Program ), DroidExplorer.Resources.Strings.SplashRunAdbAsRoot ); CommandRunner.Instance.StartAdbAsRoot(selectedDevice); // sleep a half second to let it start up. Thread.Sleep ( 500 ); } catch(AdbRootException are) { Logger.LogDebug ( typeof ( Program ), "Unable to launch ADB as root" ); // if we are unable to run as adb root if ( Settings.Instance.WarnWhenNoAdbRoot) { SplashManager.SplashDialog.Invoke((Action)(() => { SplashManager.SplashDialog.Visible = false; })); //NoAdbRootCommands Continue|Show more information|Exit var result = TaskDialog.ShowCommandBox( DroidExplorer.Resources.Strings.NoAdbRootTitle, are.Message, DroidExplorer.Resources.Strings.NoAdbRootMessage, string.Empty, string.Empty, DroidExplorer.Resources.Strings.NoAdbRootCheckboxText, DroidExplorer.Resources.Strings.NoAdbRootCommands, false, SysIcons.Warning, SysIcons.Warning); switch(TaskDialog.CommandButtonResult) { case 0: // Continue // continue if(TaskDialog.VerificationChecked) { // do not warn again. Settings.Instance.WarnWhenNoAdbRoot = false; } break; case 1: // continue and get more info : http://android.stackexchange.com/a/96066/1951 // android enthusiasts CommandRunner.Instance.LaunchProcessWindow(DroidExplorer.Resources.Strings.AdbRootQAUrl, string.Empty, true); if(TaskDialog.VerificationChecked) { // do not warn again. Settings.Instance.WarnWhenNoAdbRoot = false; } break; case 2: // link to adbd insecure by chainfire on google play CommandRunner.Instance.LaunchProcessWindow(DroidExplorer.Resources.Strings.AdbdInsecureAppUrl, string.Empty, true); Application.Exit(); return; default: // 3 Application.Exit(); return; } SplashManager.SplashDialog.Invoke((Action)(() => { SplashManager.SplashDialog.Visible = true; })); } } // increment for adb root Program.SplashManager.SplashDialog.IncrementLoadStep(1); // minor hackory for getting the device for cloud stats var d = new Core.Adb.Device(selectedDevice, Core.Adb.DeviceState.Online); // get the device properties for registration foreach(var i in CommandRunner.Instance.GetProperties(selectedDevice)) { d.Properties.Add(i.Key, i.Value); } if(!Settings.Instance.SystemSettings.RecordDeviceInformationToCloud) { Program.SplashManager.SplashDialog.SetStepText( String.Format(DroidExplorer.Resources.Strings.SplashRegisterDevice, KnownDeviceManager.Instance.GetDeviceFriendlyName(selectedDevice) ) ); // register the device CloudStatistics.Instance.RegisterDevice(d, devices.Single(x => x.SerialNumber == d.SerialNumber)); Program.SplashManager.SplashDialog.IncrementLoadStep(1); } else { // we have to increment but nothing else here Program.SplashManager.SplashDialog.IncrementLoadStep(1); } Logger.LogDebug ( typeof ( Program ), "Launching Main UI" ); // connect to device Program.SplashManager.SplashDialog.SetStepText(string.Format(DroidExplorer.Resources.Strings.SplashConnectingDevice, KnownDeviceManager.Instance.GetDeviceFriendlyName(CommandRunner.Instance.DefaultDevice))); Application.Run(new MainForm( ) ); } } catch(Exception ex) { var result = TaskDialog.ShowCommandBox(DroidExplorer.Resources.Strings.ErrorUncaughtTitle, ex.Message, DroidExplorer.Resources.Strings.ErrorUncaughtMessage, ex.ToString(), string.Empty, string.Empty, DroidExplorer.Resources.Strings.ErrorUncaughtCommands, false, SysIcons.Error, SysIcons.Error); switch(TaskDialog.CommandButtonResult) { case 1: // continue break; case 2: // android enthusiasts CommandRunner.Instance.LaunchProcessWindow(DroidExplorer.Resources.Strings.SupportUrl, string.Empty, true); break; case 3: // report bug CommandRunner.Instance.LaunchProcessWindow(DroidExplorer.Resources.Strings.IssueTrackerCreateUrl, string.Empty, true); break; default: // 0 Application.Restart(); break; } } }
static void Main(string[] arguments) { try { using (var stream = typeof(Program).Assembly.GetManifestResourceStream(DroidExplorer.Resources.Strings.Log4NetDroidExplorer)) { XmlConfigurator.Configure(stream); } var errorMessages = new List <string>(); var args = new Arguments(arguments); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); Application.ThreadException += (sender, e) => DroidExplorer.Core.Logger.LogError(typeof(Program), e.Exception.Message, e.Exception); // show the splash dialog Program.SplashManager.ShowSplashDialog(StartUpStepCount); // load settings Logger.LogDebug(typeof(Program), "Loading Droid Explorer Settings"); Program.SplashManager.SplashDialog.SetStepText("Loading Settings..."); CommandRunner.Settings = Settings.Instance; Settings.Instance.SystemSettings = RegistrySettings.Instance; Program.SplashManager.SplashDialog.IncrementLoadStep(1); // cleanup adb? should this be done? Application.ApplicationExit += delegate(object sender, EventArgs e) { //CommandRunner.Instance.AdbProcessCleanUp ( ); }; // locate sdk tools Logger.LogDebug(typeof(Program), "Locating SDK Path"); Program.SplashManager.SplashDialog.SetStepText(DroidExplorer.Resources.Strings.SplashLocatingSdk); var sdkPath = Settings.Instance.SystemSettings.SdkPath; Logger.LogDebug(typeof(Program), "SDK Path Set to {0}", sdkPath); if (string.IsNullOrEmpty(sdkPath)) { throw new ApplicationException("Unable to locate the android SDK tools, please reinstall the application."); } Program.SplashManager.SplashDialog.IncrementLoadStep(1); // verify the sdk tools Logger.LogDebug(typeof(Program), "Verifying SDK Tools"); Program.SplashManager.SplashDialog.SetStepText("Verifying SDK Tools"); // verify the sdk tools. var valid = FolderManagement.VerifyAndroidSdkTools(); if (!valid) { // if not valid - lets ask the user where it is. Program.SplashManager.SplashDialog.HideExt(); Logger.LogWarn(typeof(Program), "Unable to verify the SDK tools"); var browser = new FolderBrowserDialog(); browser.Description = "Unable to locate SDK tools path. Please select the location where you have the Android SDK installed."; browser.ShowNewFolderButton = false; var dResult = DialogResult.OK; do { dResult = browser.ShowDialog(); if (dResult == DialogResult.OK) { Settings.Instance.SystemSettings.SdkPath = browser.SelectedPath; valid = FolderManagement.VerifyAndroidSdkTools(); } // keep asking until the user selects a valid location, or they cancel. } while(!valid && dResult == DialogResult.OK); if (!valid) { // they canceled. we are out of here. throw new ApplicationException(DroidExplorer.Resources.Strings.SdkPathNotFoundMessage); } // bring it back. Program.SplashManager.SplashDialog.AsyncShow(); } Program.SplashManager.SplashDialog.IncrementLoadStep(1); // set the sdk path CommandRunner.Instance.SdkPath = sdkPath; Program.SplashManager.SplashDialog.SetStepText(DroidExplorer.Resources.Strings.SplashStartAdb); try { // start the adb server Logger.LogDebug(typeof(Program), "Starting ADB Server"); CommandRunner.Instance.StartServer(); Program.SplashManager.SplashDialog.IncrementLoadStep(1); } catch (AdbRootException arex) { Logger.LogWarn(typeof(Program), arex.Message); } // get the attached devices Program.SplashManager.SplashDialog.SetStepText(DroidExplorer.Resources.Strings.SplashGetDevices); // BUG: 15695 // fixed this. It was because adb root was disconnecting the device and restarting it. // adb root is now called when you connect to a device. Although, it can cause the device to // not be found... another bug... Logger.LogDebug(typeof(Program), "Getting connected devices"); var devices = CommandRunner.Instance.GetDevices().ToList(); Program.SplashManager.SplashDialog.IncrementLoadStep(1); new Thread(() => { // process the devices and send them off to the cloud Logger.LogDebug(typeof(Program), "Registering anonymous statistics for device types"); CloudStatistics.Instance.RegisterModels(devices); }).Start(); // we will increment even though the process is on a new thread. Program.SplashManager.SplashDialog.IncrementLoadStep(1); // pass in the initial path? // TODO: Not yet implemented. //var initialPath = "/"; //if ( args.Contains ( "p", "path" ) && !string.IsNullOrWhiteSpace ( args["p", "path"] ) ) { // initialPath = args["p", "path"]; //} // are we attaching to a specific device? if (args.Contains("d", "device")) { CommandRunner.Instance.DefaultDevice = args["d", "device"]; Logger.LogDebug(typeof(Program), DroidExplorer.Resources.Strings.SplashConnectingDevice, CommandRunner.Instance.DefaultDevice); Application.Run(new MainForm( )); } else { // get the attached devices String selectedDevice = null; if (devices.Count() != 1) { // we have 0 or > 1 so we need to display the "selection dialog" var dsf = new GenericDeviceSelectionForm(); Program.SplashManager.SplashDialog.HideExt(); if (dsf.ShowDialog(null) == DialogResult.OK) { CommandRunner.Instance.DefaultDevice = dsf.SelectedDevice; Logger.LogDebug(typeof(Program), DroidExplorer.Resources.Strings.SplashConnectingDevice, CommandRunner.Instance.DefaultDevice); selectedDevice = dsf.SelectedDevice; } else { Program.SplashManager.CloseSplashDialog(); return; } Program.SplashManager.SplashDialog.AsyncShow(); } else { selectedDevice = devices[0].SerialNumber; CommandRunner.Instance.DefaultDevice = selectedDevice; } // try to run adb as root: try { Program.SplashManager.SplashDialog.SetStepText(DroidExplorer.Resources.Strings.SplashRunAdbAsRoot); Logger.LogDebug(typeof(Program), DroidExplorer.Resources.Strings.SplashRunAdbAsRoot); CommandRunner.Instance.StartAdbAsRoot(selectedDevice); // sleep a half second to let it start up. Thread.Sleep(500); } catch (AdbRootException are) { Logger.LogDebug(typeof(Program), "Unable to launch ADB as root"); // if we are unable to run as adb root if (Settings.Instance.WarnWhenNoAdbRoot) { SplashManager.SplashDialog.Invoke((Action)(() => { SplashManager.SplashDialog.Visible = false; })); //NoAdbRootCommands Continue|Show more information|Exit var result = TaskDialog.ShowCommandBox( DroidExplorer.Resources.Strings.NoAdbRootTitle, are.Message, DroidExplorer.Resources.Strings.NoAdbRootMessage, string.Empty, string.Empty, DroidExplorer.Resources.Strings.NoAdbRootCheckboxText, DroidExplorer.Resources.Strings.NoAdbRootCommands, false, SysIcons.Warning, SysIcons.Warning); switch (TaskDialog.CommandButtonResult) { case 0: // Continue // continue if (TaskDialog.VerificationChecked) { // do not warn again. Settings.Instance.WarnWhenNoAdbRoot = false; } break; case 1: // continue and get more info : http://android.stackexchange.com/a/96066/1951 // android enthusiasts CommandRunner.Instance.LaunchProcessWindow(DroidExplorer.Resources.Strings.AdbRootQAUrl, string.Empty, true); if (TaskDialog.VerificationChecked) { // do not warn again. Settings.Instance.WarnWhenNoAdbRoot = false; } break; case 2: // link to adbd insecure by chainfire on google play CommandRunner.Instance.LaunchProcessWindow(DroidExplorer.Resources.Strings.AdbdInsecureAppUrl, string.Empty, true); Application.Exit(); return; default: // 3 Application.Exit(); return; } SplashManager.SplashDialog.Invoke((Action)(() => { SplashManager.SplashDialog.Visible = true; })); } } // increment for adb root Program.SplashManager.SplashDialog.IncrementLoadStep(1); // minor hackory for getting the device for cloud stats var d = new Core.Adb.Device(selectedDevice, Core.Adb.DeviceState.Online); // get the device properties for registration foreach (var i in CommandRunner.Instance.GetProperties(selectedDevice)) { d.Properties.Add(i.Key, i.Value); } if (!Settings.Instance.SystemSettings.RecordDeviceInformationToCloud) { Program.SplashManager.SplashDialog.SetStepText( String.Format(DroidExplorer.Resources.Strings.SplashRegisterDevice, KnownDeviceManager.Instance.GetDeviceFriendlyName(selectedDevice) ) ); // register the device CloudStatistics.Instance.RegisterDevice(d, devices.Single(x => x.SerialNumber == d.SerialNumber)); Program.SplashManager.SplashDialog.IncrementLoadStep(1); } else { // we have to increment but nothing else here Program.SplashManager.SplashDialog.IncrementLoadStep(1); } Logger.LogDebug(typeof(Program), "Launching Main UI"); // connect to device Program.SplashManager.SplashDialog.SetStepText(string.Format(DroidExplorer.Resources.Strings.SplashConnectingDevice, KnownDeviceManager.Instance.GetDeviceFriendlyName(CommandRunner.Instance.DefaultDevice))); Application.Run(new MainForm( )); } } catch (Exception ex) { var result = TaskDialog.ShowCommandBox(DroidExplorer.Resources.Strings.ErrorUncaughtTitle, ex.Message, DroidExplorer.Resources.Strings.ErrorUncaughtMessage, ex.ToString(), string.Empty, string.Empty, DroidExplorer.Resources.Strings.ErrorUncaughtCommands, false, SysIcons.Error, SysIcons.Error); switch (TaskDialog.CommandButtonResult) { case 1: // continue break; case 2: // android enthusiasts CommandRunner.Instance.LaunchProcessWindow(DroidExplorer.Resources.Strings.SupportUrl, string.Empty, true); break; case 3: // report bug CommandRunner.Instance.LaunchProcessWindow(DroidExplorer.Resources.Strings.IssueTrackerCreateUrl, string.Empty, true); break; default: // 0 Application.Restart(); break; } } }
/// <summary> /// Gets the screen shot. /// </summary> /// <returns></returns> private Image GetScreenShot( ) { Device d = new Device ( CommandRunner.Instance.DefaultDevice, DeviceState.Online ); RawImage ri = AdbHelper.Instance.GetFrameBuffer ( AndroidDebugBridge.SocketAddress, d ); return GetImageFromRawImage ( ri ); }