/// <summary> /// Uploads a file to the device in the specified folder (or direct path) /// </summary> /// <param name="device">Optional if there is only one device attached</param> /// <param name="filePath"></param> /// <param name="destPath">May contain the file name. If it doesn't, the original file name will be used</param> /// <returns>True on success, false if was not able to create the destination directory or write the file</returns> public bool Push(Device device, string filePath, string destPath) { // check if local file exists if (!File.Exists(filePath)) { return(false); } var destFileName = Path.GetFileName(destPath); var destDirectory = Path.GetDirectoryName(destPath).WindowsToUnixPath(); if (String.IsNullOrEmpty(destFileName)) { destFileName = Path.GetFileName(filePath); } // create the destination path var mkdir = Shell(device, "mkdir -p", destDirectory); if (ExeResponse.IsNullOrAbnormalExit(mkdir) || mkdir.Output.Contains("failed")) { Debug.WriteLine("Unable to create directory " + destDirectory); return(false); } // setup the arguments var arguments = new[] { filePath, destDirectory + "/" + destFileName }; // execute var push = Execute(device, CommandPush, arguments); return(!ExeResponse.IsNullOrAbnormalExit(push) && !push.Output.Contains("failed")); }
/// <summary> /// Remount the system partition as rw /// </summary> /// <param name="device">If null, the first connected device will trigger the end of the method.</param> /// <returns></returns> public bool RemountSystem(Device device) { var exec = Execute(device, CommandRemount); return(!ExeResponse.IsNullOrAbnormalExit(exec) && exec.ExitCode == 0 && exec.Output.IndexOf("remount failed", StringComparison.CurrentCultureIgnoreCase) == -1); }
/// <summary> /// Restart the adb server as root for the specified device /// </summary> /// <param name="device">If null, the first connected device will trigger the end of the method.</param> /// <returns></returns> public bool StartAsRoot(Device device) { var exec = Execute(device, CommandStartRoot); return(!ExeResponse.IsNullOrAbnormalExit(exec) && exec.ExitCode == 0 && exec.Output.IndexOf("cannot run", StringComparison.CurrentCultureIgnoreCase) == -1); }
/// <summary> /// Uninstall a package from the device /// </summary> /// <param name="device">If null, the first device in the list will be used.</param> /// <param name="packageName">The package name of the application to uninstall</param> /// <param name="keepData">If true, the process will maintain the user's data</param> /// <returns></returns> public bool Uninstall(Device device, string packageName, bool keepData) { var execute = keepData ? Execute(device, CommandUninstall, "-k") : Execute(device, CommandUninstall); return(!ExeResponse.IsNullOrAbnormalExit(execute) && execute.Output.IndexOf("success", StringComparison.CurrentCultureIgnoreCase) > 0); }
/// <summary> /// Retrieves a file from the device /// </summary> /// <param name="device"></param> /// <param name="sourcePath"></param> /// <param name="destPath">May contain the file name. If it doesn't, the original file name will be used</param> /// <returns></returns> public bool Pull(Device device, string sourcePath, string destPath) { var destDirectory = Path.GetFullPath(destPath); var destFileName = Path.GetFileName(destPath); if (String.IsNullOrEmpty(destFileName)) { destFileName = Path.GetFileName(sourcePath); } var execute = Execute(device, CommandPull, sourcePath, Path.Combine(new[] { destDirectory, destFileName }).WrapInQuotes()); return(!ExeResponse.IsNullOrAbnormalExit(execute) && !execute.Output.Contains("not exist")); }
public void Load(Device device) { if (PropsList.Count > 0) { return; } var raw = Exe.Adb(device, new[] { "shell", "cat /system/build.prop" }); if (ExeResponse.IsNullOrAbnormalExit(raw)) { return; } var lines = raw.Output.Split(new[] { Environment.NewLine }, StringSplitOptions.None); PropsList.Clear(); foreach (var matches in lines.Select(line => Regex.Match(line, PropRegex, RegexOptions.IgnoreCase)).Where(matches => matches.Success)) { PropsList.Add(matches.Groups["prop"].Value, matches.Groups["value"].Value); } }
/// <summary> /// Install a local APK on the device /// </summary> /// <param name="device">If null, the first device in the list will be used.</param> /// <param name="pathToApk">Path to the APK file to install</param> /// <param name="forwardLock">(Deprecated by Google!) installs the application on a read-only space</param> /// <param name="reinstall">Reinstall instead of installing as new, preserving the user's data</param> /// <param name="onSdCard">Try to install the application on the sdcard instead of the internal storage</param> /// <param name="encryption">If not null, it allows to setup the encryption details, if the apk is encrypted</param> /// <returns></returns> public bool Install(Device device, string pathToApk, bool forwardLock, bool reinstall, bool onSdCard, ApkEncryption encryption) { var parameters = new List <string>(); if (!File.Exists(pathToApk)) { return(false); } if (forwardLock) { parameters.Add("-l"); } if (reinstall) { parameters.Add("-r"); } if (onSdCard) { parameters.Add("-s"); } if (encryption != null && encryption.IsComplete) { parameters.AddRange(new[] { "--algo", encryption.Algorithm, "--key", encryption.Key, "--iv", encryption.IV }); } parameters.Add(pathToApk.WrapInQuotes()); var execute = Execute(device, CommandInstall, parameters.ToArray()); return(!ExeResponse.IsNullOrAbnormalExit(execute) && execute.Output.IndexOf("success", StringComparison.CurrentCultureIgnoreCase) > 0); }
/// <summary> /// Retrieves a list of currently connected <see cref="Device"/>s (in debug mode). /// Drivers must be correctly installed to let ADB see the devices. /// </summary> /// <returns></returns> public List <Device> GetDevicesList() { var output = Exe.Adb(null, new[] { "devices" }); if (ExeResponse.IsNullOrAbnormalExit(output)) { return(null); } var cursor = output.Output.Split(new[] { Environment.NewLine }, StringSplitOptions.None).GetEnumerator(); var devices = new List <Device>(); while (cursor.MoveNext()) { var current = cursor.Current as string; if (String.IsNullOrEmpty(current)) { continue; } var matches = Regex.Match(current, "^(?<serial>[a-z|0-9]+)[\\s]+(?<state>[a-z|0-9]+)$"); if (!matches.Success) { continue; } devices.Add(new Device { Build = new Build(matches.Groups["serial"].Value), SerialNumber = matches.Groups["serial"].Value }); } return(devices); }
/// <summary> /// Executes adb and returns the current state of the device (<see cref="StateUnknown"/> if not found or on error) /// </summary> /// <param name="device"></param> /// <returns></returns> public string GetDeviceState(Device device) { var exec = Execute(device, "get-state"); return(ExeResponse.IsNullOrAbnormalExit(exec) ? StateUnknown : exec.Output); }
/// <summary> /// Deletes a device's file or directory (recusively). /// </summary> /// <param name="device">If null, the first device in the list will be used.</param> /// <param name="pathToFileOrDirectory">Must be escaped UNIX style (<see cref="Extensions.EscapeSpacesUnixStyle"/>)</param> /// <returns></returns> public bool Delete(Device device, string pathToFileOrDirectory) { var execute = Shell(device, "rm -rf", pathToFileOrDirectory); return(!ExeResponse.IsNullOrAbnormalExit(execute) && String.IsNullOrEmpty(execute.Output)); }