/// <include file='.\BusyBox.xml' path='/BusyBox/ExecuteRootShellCommand/*'/> public void ExecuteRootShellCommand( String command, IShellOutputReceiver receiver, params object[] commandArgs ) { command.ThrowIfNullOrWhiteSpace ( "command" ); var cmd = String.Format ( "{0} {1}", BUSYBOX_COMMAND, String.Format ( command, commandArgs ) ); Log.d ( "executing (su): {0}", cmd ); Device.ExecuteRootShellCommand(cmd, receiver ); }
/// <summary> /// Chmods the specified path. /// </summary> /// <param name="path">The path.</param> /// <param name="permissions">The permissions.</param> public void Chmod( String path, FilePermissions permissions ) { Device.ThrowIfNull ( "Device" ); path.ThrowIfNullOrWhiteSpace ( "path" ); permissions.ThrowIfNull ( "permissions" ); FileEntry entry = Device.FileListingService.FindFileEntry ( path ); CommandErrorReceiver cer = new CommandErrorReceiver ( ); Device.ExecuteShellCommand ( "chmod {0} {1}", cer, permissions.ToChmod ( ), entry.FullEscapedPath ); }
/// <summary> /// Executes a busybox command on the device as root /// </summary> /// <param name="command">The command.</param> /// <param name="receiver">The receiver.</param> /// <param name="commandArgs">The command args.</param> public void ExecuteRootShellCommand( String command, IShellOutputReceiver receiver, params object[] commandArgs ) { command.ThrowIfNullOrWhiteSpace ( "command" ); var cmd = String.Format ( "{0} {1}", BUSYBOX_COMMAND, String.Format ( command, commandArgs ) ); Log.d ( "executing (su): {0}", cmd ); AdbHelper.Instance.ExecuteRemoteRootCommand ( AndroidDebugBridge.SocketAddress, cmd, this.Device, receiver ); }
/// <summary> /// Gets if the specified command name is supported by this version of busybox /// </summary> /// <param name="command">The command name to check</param> /// <returns><c>true</c>, if supported; otherwise, <c>false</c>.</returns> public bool Supports( String command ) { command.ThrowIfNullOrWhiteSpace ( "command" ); if ( Available && ( Commands == null || Commands.Count == 0 ) ) { CheckForBusyBox ( ); } return Commands.Where( c => String.Compare(c,command,false) == 0).FirstOrDefault() != null; }
/// <summary> /// Attempts to install on the device /// </summary> /// <param name="busybox">The path to the busybox binary to install.</param> /// <returns><c>true</c>, if successful; otherwise, <c>false</c></returns> public bool Install( String busybox ) { busybox.ThrowIfNullOrWhiteSpace ( "busybox" ); FileEntry bb = null; try { Device.ExecuteShellCommand ( BUSYBOX_COMMAND, NullOutputReceiver.Instance ); return true; } catch { // we are just checking if it is already installed so we really expect it to wind up here. } try { MountPoint mp = Device.MountPoints["/data"]; bool isRO = mp.IsReadOnly; Device.RemountMountPoint ( Device.MountPoints["/data"], false ); FileEntry path = null; try { path = Device.FileListingService.FindFileEntry ( BUSYBOX_BIN ); } catch ( FileNotFoundException ) { // path doesn't exist, so we make it. Device.FileSystem.MakeDirectory ( BUSYBOX_BIN ); // attempt to get the FileEntry after the directory has been made path = Device.FileListingService.FindFileEntry ( BUSYBOX_BIN ); } Device.FileSystem.Chmod ( path.FullPath, "0755" ); String bbPath = LinuxPath.Combine ( path.FullPath, BUSYBOX_COMMAND ); Device.FileSystem.Copy ( busybox, bbPath ); bb = Device.FileListingService.FindFileEntry ( bbPath ); Device.FileSystem.Chmod ( bb.FullPath, "0755" ); Device.ExecuteShellCommand ( "{0}/busybox --install {0}", new ConsoleOutputReceiver ( ), path.FullPath ); // check if this path exists in the path already if ( Device.EnvironmentVariables.ContainsKey ( "PATH" ) ) { var paths = Device.EnvironmentVariables["PATH"].Split ( ':' ); var found = paths.Where ( p => String.Compare ( p, BUSYBOX_BIN, false ) == 0 ).Count ( ) > 0; // we didnt find it, so add it. if ( !found ) { // this doesn't seem to actually work Device.ExecuteShellCommand ( @"echo \ Mad Bee buxybox >> /init.rc", NullOutputReceiver.Instance ); Device.ExecuteShellCommand ( @"echo export PATH={0}:\$PATH >> /init.rc", NullOutputReceiver.Instance, BUSYBOX_BIN ); } } if ( mp.IsReadOnly != isRO ) { // Put it back, if we changed it Device.RemountMountPoint ( mp, isRO ); } Device.ExecuteShellCommand ( "sync", NullOutputReceiver.Instance ); } catch ( Exception ) { throw; } CheckForBusyBox ( ); return true; }
/// <summary> /// Copies the specified source to the specified destination. /// </summary> /// <param name="source">The source.</param> /// <param name="destination">The destination.</param> public void Copy( String source, String destination ) { Device.ThrowIfNull ( "Device" ); source.ThrowIfNullOrWhiteSpace ( "source" ); destination.ThrowIfNullOrWhiteSpace ( "destination" ); CommandErrorReceiver cer = new CommandErrorReceiver ( ); FileEntry sfe = Device.FileListingService.FindFileEntry ( source ); Device.ExecuteShellCommand ( "cat {0} > {1}", cer, sfe.FullEscapedPath, destination ); if ( !String.IsNullOrEmpty ( cer.ErrorMessage ) ) { throw new IOException ( cer.ErrorMessage ); } }
/// <summary> /// Makes the directory. /// </summary> /// <param name="path">The path.</param> /// <param name="forceDeviceMethod">if set to <c>true</c> forces the use of the "non-busybox" method.</param> public void MakeDirectory( String path, bool forceDeviceMethod ) { Device.ThrowIfNull ( "Device" ); path.ThrowIfNullOrWhiteSpace ( "path" ); CommandErrorReceiver cer = new CommandErrorReceiver ( ); try { //var fileEntry = FileEntry.FindOrCreate ( Device, path ); // if we have busybox we can use the mkdir in there as it supports --parents if ( Device.BusyBox.Available && !forceDeviceMethod ) { try { Device.BusyBox.ExecuteShellCommand ( "mkdir -p {0}", cer, path ); } catch { try { // if there was an error, then fallback too. MakeDirectoryFallbackInternal ( path, cer ); } catch { } } } else { // if busybox is not available then we have to fallback MakeDirectoryFallbackInternal ( path, cer ); } } catch { } if ( !String.IsNullOrEmpty ( cer.ErrorMessage ) ) { throw new IOException ( cer.ErrorMessage ); } }
/// <summary> /// Gets if the specified mount point is read-only /// </summary> /// <param name="mount"></param> /// <returns><code>true</code>, if read-only; otherwise, <code>false</code></returns> /// <exception cref="IOException">If mount point doesnt exist</exception> public bool IsMountPointReadOnly( String mount ) { Device.ThrowIfNull ( "Device" ); mount.ThrowIfNullOrWhiteSpace ( mount ); if ( !Device.MountPoints.ContainsKey ( mount ) ) { throw new IOException ( "Invalid mount point" ); } return Device.MountPoints[mount].IsReadOnly; }
/// <summary> /// Gets if the specified path exists on the device. /// </summary> /// <param name="path">the path to check</param> /// <returns><c>true</c>, if the path exists; otherwise, <c>false</c></returns> /// <exception cref="IOException">If the device is not connected.</exception> /// <exception cref="ArgumentNullException">If the device or path is null.</exception> public bool Exists( String path ) { Device.ThrowIfNull ( "Device" ); path.ThrowIfNullOrWhiteSpace ( "path" ); if ( !Device.IsOffline ) { try { FileEntry fe = Device.FileListingService.FindFileEntry ( path ); return fe != null; } catch ( FileNotFoundException e ) { return false; } } else { throw new IOException ( "Device is not online" ); } }
/// <summary> /// Deletes the specified path. /// </summary> /// <param name="path">The path.</param> /// <exception cref="System.ArgumentNullException"> /// If device is null /// or /// If path is null or empty. /// </exception> /// <gist id="adee6a11c5441da61af8" /> /// <exception cref="System.IO.IOException">If the command fails.</exception> public void Delete(String path) { Device.ThrowIfNull ( "Device" ); path.ThrowIfNullOrWhiteSpace ( "path" ); FileEntry entry = Device.FileListingService.FindFileEntry ( path ); Delete ( entry ); }
/// <summary> /// Creates the specified path. /// </summary> /// <param name="path">The path.</param> /// <returns></returns> public FileEntry Create( String path ) { Device.ThrowIfNull ( "Device" ); path.ThrowIfNullOrWhiteSpace ( "path" ); if ( !Device.IsOffline ) { if ( Exists ( path ) ) { throw new ArgumentException ( "The specified path already exists." ); } else { var cer = new CommandErrorReceiver ( ); var escaped = LinuxPath.Escape ( path ); // use native touch command if its available. var cmd = Device.BusyBox.Available ? "touch" : ">"; var command = String.Format ( "{0} {1}", cmd, escaped ); if ( Device.CanSU ( ) ) { Device.ExecuteRootShellCommand ( command, cer ); } else { Device.ExecuteShellCommand ( command, cer ); } if ( !String.IsNullOrEmpty ( cer.ErrorMessage ) ) { throw new IOException ( String.Format ( "Error creating file: {0}", cer.ErrorMessage ) ); } else { // at this point, the newly created file should exist. return Device.FileListingService.FindFileEntry ( path ); } } } else { throw new IOException ( "Device is not online" ); } }
/// <summary> /// Makes the directory. /// </summary> /// <param name="path">The path.</param> /// <param name="forceDeviceMethod">if set to <see langword="true"/> forces the use of the "non-busybox" method.</param> public void MakeDirectory(String path, bool forceDeviceMethod) { Device.ThrowIfNull("Device"); path.ThrowIfNullOrWhiteSpace("path"); CommandErrorReceiver cer = new CommandErrorReceiver(); try { // if busybox is not available then we have to fallback MakeDirectoryFallbackInternal(path, cer); } catch { } if (!String.IsNullOrEmpty(cer.ErrorMessage)) { throw new IOException(cer.ErrorMessage); } }
/// <include file='.\BusyBox.xml' path='/BusyBox/ExecuteShellCommand/*'/> public void ExecuteShellCommand( String command, IShellOutputReceiver receiver, params object[] commandArgs ) { command.ThrowIfNullOrWhiteSpace ( "command" ); var cmd = String.Format ( "{0} {1}", BUSYBOX_COMMAND, String.Format ( command, commandArgs ) ); Log.d ( "executing: {0}", cmd ); AdbClient.Instance.ExecuteRemoteCommand(cmd, this.Device.DeviceData, receiver); }
/// <summary> /// Deletes the specified path. /// </summary> /// <param name="path">The path.</param> public void Delete( String path ) { Device.ThrowIfNull ( "Device" ); path.ThrowIfNullOrWhiteSpace ( "path" ); CommandErrorReceiver cer = new CommandErrorReceiver ( ); FileEntry entry = Device.FileListingService.FindFileEntry ( path ); Delete ( entry ); }