示例#1
0
        /// <summary>
        /// Runs <code>adb (command)</code> and returns the result.
        /// AdbException is thrown if the return code is non-zero, unless the return code is in allowedExitCodes.
        /// </summary>
        /// <param name="command">The command to execute, without the <code>adb</code> executable name</param>
        /// <returns>The process output from executing the file</returns>
        public async Task <ProcessOutput> RunCommand(string command, params int[] allowedExitCodes)
        {
            if (_adbPath == null)
            {
                await PrepareAdbPath();
            }
            Debug.Assert(_adbPath != null);

            _logger.Debug($"Executing ADB command: adb {command}");
            while (true)
            {
                ProcessOutput output = await ProcessUtil.InvokeAndCaptureOutput(_adbPath, command);

                _logger.Verbose($"Standard output: \"{output.StandardOutput}\"");
                if (output.ErrorOutput.Length > 0)
                {
                    _logger.Verbose($"Error output: \"{output.ErrorOutput}\"");
                }
                _logger.Verbose($"Exit code: {output.ExitCode}");

                // Command execution was a success if the exit code was zero or an allowed exit code
                // -1073740940 is always allowed as some ADB installations return it randomly, even when commands are successful.
                if (output.ExitCode == 0 || allowedExitCodes.Contains(output.ExitCode) || output.ExitCode == -1073740940)
                {
                    return(output);
                }

                string allOutput = output.StandardOutput + output.ErrorOutput;

                // We repeatedly prompt the user to plug in their quest if it is not plugged in, or the device is offline, or if there are multiple devices
                if (allOutput.Contains("no devices/emulators found"))
                {
                    await _onDisconnect(DisconnectionType.NoDevice);
                }
                else if (allOutput.Contains("device offline"))
                {
                    await _onDisconnect(DisconnectionType.DeviceOffline);
                }
                else if (allOutput.Contains("multiple devices") || output.ErrorOutput.Contains("more than one device/emulator"))
                {
                    await _onDisconnect(DisconnectionType.MultipleDevices);
                }
                else if (allOutput.Contains("unauthorized"))
                {
                    await _onDisconnect(DisconnectionType.Unauthorized);
                }
                else
                {
                    // Throw an exception as ADB gave a non-zero exit code so the command must've failed
                    throw new AdbException(allOutput);
                }
            }
        }
示例#2
0
        /// <summary>
        /// Checks if ADB is on PATH, and downloads it if not
        /// </summary>
        public async Task PrepareAdbPath()
        {
            try
            {
                await ProcessUtil.InvokeAndCaptureOutput(_adbExecutableName, "-version");

                // If the ADB EXE is already on PATH, we can just use that
                _adbPath = _adbExecutableName;
                _logger.Information("Located ADB install on PATH");
            }
            catch (Win32Exception) // Thrown if the file we attempted to execute does not exist (on mac & linux as well, despite saying Win32)
            {
                // Otherwise, we download the tool and make it executable (only necessary on mac & linux)
                _adbPath = await _filesDownloader.GetFileLocation(ExternalFileType.PlatformTools); // Download ADB if it hasn't been already
            }
        }
示例#3
0
 private Task <ProcessOutput> InvokeJava(string args)
 {
     return(ProcessUtil.InvokeAndCaptureOutput(_javaExecutableName, args));
 }