您的位置:首页 > 运维架构 > Shell

Unity: CommandRunner.cs (csharp run adb shell on adroid)

2016-03-10 15:08 477 查看
from: https://searchcode.com/codesearch/view/5667336/
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Drawing;
using ICSharpCode.SharpZipLib.Zip;
using DroidExplorer.Core.IO;
using System.Threading;
using System.Globalization;
using DroidExplorer.Core.Components;
using DroidExplorer.Core.Exceptions;
using System.ComponentModel;
using DroidExplorer.Core.Plugins;
using DroidExplorer.Core.Collections;
using DroidExplorer.Core.Configuration;
using System.Xml.Serialization;
using System.Drawing.Imaging;
using Managed.Adb.IO;
using Managed.Adb;
using System.Net;
using Managed.Adb.Exceptions;

namespace DroidExplorer.Core {
/// <summary>
///
/// </summary>
public class CommandRunner {
private static CommandRunner _commandRunner;

/// <summary>
/// Occurs when [device state changed].
/// </summary>
public event EventHandler<DeviceEventArgs> DeviceStateChanged;
/// <summary>
/// Occurs when [connected].
/// </summary>
public event EventHandler<DeviceEventArgs> Connected;
/// <summary>
/// Occurs when [disconnected].
/// </summary>
public event EventHandler<DeviceEventArgs> Disconnected;
/// <summary>
/// Occurs when [top process updated].
/// </summary>
public event EventHandler<ProcessInfoEventArgs> TopProcessUpdated;
/// <summary>
/// Occurs when [top process update complete].
/// </summary>
public event EventHandler TopProcessUpdateComplete;
/// <summary>
/// Occurs when [top process update started].
/// </summary>
public event EventHandler TopProcessUpdateStarted;
/// <summary>
///
/// </summary>
public enum AaptCommand {
/// <summary>
///
/// </summary>
Dump_Badging,
/// <summary>
///
/// </summary>
Dump_Permissions,
/// <summary>
///
/// </summary>
Dump_Resources,
/// <summary>
///
/// </summary>
Dump_Configuration,
/// <summary>
///
/// </summary>
Dump_XmlTree,
/// <summary>
///
/// </summary>
Dump_XmlStrings,
/// <summary>
///
/// </summary>
List,
/// <summary>
///
/// </summary>
Package,
/// <summary>
///
/// </summary>
Remove,
/// <summary>
///
/// </summary>
Add,
/// <summary>
///
/// </summary>
Version,
}

/// <summary>
///
/// </summary>
public enum AdbCommand {
/// <summary>
///
/// </summary>
Devices,
/// <summary>
///
/// </summary>
Help,
/// <summary>
///
/// </summary>
Root,
/// <summary>
///
/// </summary>
Remount,
/// <summary>
///
/// </summary>
Status_Window,
/// <summary>
///
/// </summary>
Get_SerialNo,
/// <summary>
///
/// </summary>
Get_State,
/// <summary>
///
/// </summary>
Kill_Server,
/// <summary>
///
/// </summary>
Start_Server,
/// <summary>
///
/// </summary>
Wait_For_Device,
/// <summary>
///
/// </summary>
Version,
/// <summary>
///
/// </summary>
Bugreport,
/// <summary>
///
/// </summary>
Uninstall,
/// <summary>
///
/// </summary>
Install,
/// <summary>
///
/// </summary>
Jdwp,
/// <summary>
///
/// </summary>
Forward,
/// <summary>
///
/// </summary>
Logcat,
/// <summary>
///
/// </summary>
Emu,
/// <summary>
///
/// </summary>
Shell,
/// <summary>
///
/// </summary>
Sync,
/// <summary>
///
/// </summary>
Push,
/// <summary>
///
/// </summary>
Pull,
/// <summary>
///
/// </summary>
PPP,
/// <summary>
///
/// </summary>
ShellLS,
/// <summary>
///
/// </summary>
ShellPackageManager,
}

/// <summary>
///
/// </summary>
public const string SYSTEM_APP_PATH = "/system/app/";
/// <summary>
///
/// </summary>
public const string APP_PUBLIC_PATH = "/data/app/";

/// <summary>
///
/// </summary>
public const string APP_SD_PUBLIC_PATH = "/sd-ext/app/";

/// <summary>
///
/// </summary>
public const string APP_PRIVATE_PATH = "/data/app-private/";

/// <summary>
///
/// </summary>
public const string APP_SD_PRIVATE_PATH = "/sd-ext/app-private/";
/// <summary>
///
/// </summary>
public const string TEMP_DIRECTORY = "DroidExplorer";

private DeviceState _deviceState = DeviceState.Unknown;

/// <summary>
/// Initializes a new instance of the <see cref="CommandRunner"/> class.
/// </summary>
public CommandRunner ( ) {
if ( Settings == null ) {
throw new ArgumentNullException ( "Settings not set. Must initialize settings before getting CommandRunner instance." );
}
String tsdk = Settings.SystemSettings.SdkPath;
if ( String.IsNullOrEmpty ( tsdk ) || !System.IO.Directory.Exists(tsdk) ) {
SdkPath = System.IO.Path.Combine ( AssemblyDirectory, "sdk" );
} else {
SdkPath = tsdk;
}
}

/// <summary>
/// Gets the assembly directory.
/// </summary>
/// <value>The assembly directory.</value>
public string AssemblyDirectory {
get {
return System.IO.Path.GetDirectoryName ( this.GetType ( ).Assembly.Location );
}
}

/// <summary>
/// Gets the SDK tool.
/// </summary>
/// <param name="relativePath">The relative path.</param>
/// <returns></returns>
public string GetSdkTool ( string relativePath ) {
//return System.IO.Path.Combine ( SdkPath, relativePath );
String sdkTool = System.IO.Path.Combine ( Settings.SystemSettings.SdkToolsPath, relativePath );
String platformTool = System.IO.Path.Combine ( Settings.SystemSettings.PlatformToolsPath, relativePath );
if ( System.IO.File.Exists ( sdkTool ) ) {
return sdkTool;
} else if ( System.IO.File.Exists ( platformTool ) ) {
return platformTool;
} else {
throw new System.IO.FileNotFoundException ( String.Format ( "Unable to located {0} in the SDK path", relativePath ) );
}
}

/// <summary>
/// Verifies the android SDK tools.
/// </summary>
/// <returns></returns>
public bool VerifyAndroidSdkTools ( ) {
try {
return System.IO.File.Exists ( GetSdkTool ( AndroidDebugBridge.ADB ) ) && System.IO.File.Exists ( GetSdkTool ( AndroidDebugBridge.AAPT ) );
} catch ( Exception ex ) {
return false;
}
}

/// <summary>
/// Launches the activity.
/// </summary>
/// <param name="package">The package.</param>
/// <param name="classFullName">Full name of the class.</param>
public void LaunchActivity ( string package, string classFullName ) {
LaunchActivity ( this.DefaultDevice, package, classFullName );
}

/// <summary>
/// Launches the activity.
/// </summary>
/// <param name="device">The device.</param>
/// <param name="package">The package.</param>
/// <param name="classFullName">Full name of the class.</param>
public void LaunchActivity( Device device, string package, string classFullName ) {
//ShellRun ( device, string.Format ( CultureInfo.InvariantCulture, "am start -a android.intent.action.MAIN -n {0}/{1}", package, classFullName ) );
device.ExecuteShellCommand ( "am start -a android.intent.action.MAIN -n {0}/{1}", ConsoleOutputReceiver.Instance, package, classFullName );
}

/// <summary>
/// Makes the mount point read write.
/// </summary>
/// <param name="device">The device.</param>
/// <param name="mountPoint">The mount point.</param>
public void MakeReadWrite( Device device, string mountPoint ) {
if ( !mountPoint.StartsWith ( "/" ) ) {
throw new DroidExplorer.Core.Exceptions.AdbException ( "Invalid mount point" );
}
//ShellRun ( device, string.Format ( CultureInfo.InvariantCulture, "busybox mount -o rw,remount {0}", mountPoint ) );
device.RemountMountPoint ( mountPoint, true );
}

/// <summary>
/// Makes the mount point read write.
/// </summary>
/// <param name="mountPoint">The mount point.</param>
public void MakeReadWrite ( string mountPoint ) {
MakeReadWrite ( this.DefaultDevice, mountPoint );
}

/// <summary>
/// Makes the mount point read only.
/// </summary>
/// <param name="device">The device.</param>
/// <param name="mountPoint">The mount point.</param>
public void MakeReadOnly( Device device, string mountPoint ) {
if ( !mountPoint.StartsWith ( "/" ) ) {
throw new DroidExplorer.Core.Exceptions.AdbException ( "Invalid mount point" );
}
device.RemountMountPoint ( mountPoint, true );
//ShellRun ( device, string.Format ( CultureInfo.InvariantCulture, "busybox mount -o ro,remount {0}", mountPoint ) );
}

/// <summary>
/// Makes the mount point read only.
/// </summary>
/// <param name="mountPoint">The mount point.</param>
public void MakeReadOnly ( string mountPoint ) {
MakeReadOnly ( this.DefaultDevice, mountPoint );
}

/// <summary>
/// Gets or sets the default device.
/// </summary>
/// <value>The default device.</value>
public Device DefaultDevice { get; set; }

/// <summary>
/// Gets the path of the SDK Tools
/// </summary>
public string SdkPath { get; set; }

/// <summary>
/// Gets or sets the top process.
/// </summary>
/// <value>The top process.</value>
private Process TopProcess { get; set; }

/// <summary>
/// Gets or sets the status process.
/// </summary>
/// <value>The status process.</value>
private Process StatusProcess { get; set; }

/// <summary>
/// Connects the specified device.
/// </summary>
/// <param name="device">The device.</param>
/*public void Connect ( string device ) {
try {
if ( StatusProcess == null || StatusProcess.HasExited ) {
StatusProcess = new Process ( );
ProcessStartInfo psi = new ProcessStartInfo ( GetSdkTool ( ADB_COMMAND ), AdbCommandArguments ( device, AdbCommand.Status_Window ) );
psi.CreateNoWindow = true;
psi.ErrorDialog = false;
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;

StatusProcess.StartInfo = psi;
StatusProcess.OutputDataReceived += delegate ( object sender, DataReceivedEventArgs e ) {
if ( !string.IsNullOrEmpty ( e.Data ) ) {
Regex regex = new Regex ( @"state\:\s+((device)|(unknown)|(offline)|(bootloader)|(recovery))", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace );
Match m = regex.Match ( e.Data );
if ( m.Success ) {
DeviceState pstate = State;
State = StringToDeviceState ( m.Result ( "$1" ) );

if ( State == DeviceState.Unknown ) {
State = this.GetDeviceState ( device );
}

if ( State == DeviceState.Device || State == DeviceState.Recovery ) {
if ( this.Connected != null ) {
this.Connected ( this, new DeviceEventArgs ( device, State ) );
}
} else {
if ( this.Disconnected != null ) {
this.Disconnected ( this, new DeviceEventArgs ( device, State ) );
}
}
if ( pstate != State ) {
if ( this.DeviceStateChanged != null ) {
this.DeviceStateChanged ( this, new DeviceEventArgs ( device, State ) );
}
}
}
}
};

StatusProcess.ErrorDataReceived += delegate ( object sender, DataReceivedEventArgs e ) {
};

StatusProcess.Exited += delegate ( object sender, EventArgs e ) {
if ( State == DeviceState.Device ) {
Disconnect ( );
}
};
StatusProcess.Start ( );
StatusProcess.BeginOutputReadLine ( );
StatusProcess.BeginErrorReadLine ( );
}
} catch ( Exception ex ) {
this.LogError ( ex.Message, ex );
State = DeviceState.Unknown;
}
}*/

/// <summary>
/// Tops the process kill.
/// </summary>
/*public void TopProcessKill ( ) {
if ( TopProcess != null && !TopProcess.HasExited ) {
try {
TopProcess.Kill ( );
} catch {
}
}
}*/

/// <summary>
/// Tops the process run.
/// </summary>
/*public void TopProcessRun ( ) {
try {
if ( TopProcess == null || TopProcess.HasExited ) {
TopProcess = new Process ( );
ProcessStartInfo psi = new ProcessStartInfo ( GetSdkTool ( ADB_COMMAND ), string.Format ( CultureInfo.InvariantCulture, "{0} top -d 1 -s cpu", AdbCommandArguments ( DefaultDevice, AdbCommand.Shell ) ) );
psi.CreateNoWindow = true;
psi.ErrorDialog = false;
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;

TopProcess.StartInfo = psi;
TopProcess.OutputDataReceived += delegate ( object sender, DataReceivedEventArgs e ) {
if ( TopProcessUpdateStarted != null ) {
TopProcessUpdateStarted ( this, EventArgs.Empty );
}
Regex regex = new Regex ( Properties.Resources.TopProcessRegexPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace |
RegexOptions.Multiline );
if ( string.IsNullOrEmpty ( e.Data ) ) {
return;
}

Match m = regex.Match ( e.Data );
while ( m.Success ) {
int pid = 0;
int.TryParse ( m.Groups[ 1 ].Value, out pid );
int cpu = 0;
int.TryParse ( m.Groups[ 2 ].Value, out cpu );
int thread = 0;
int.TryParse ( m.Groups[ 4 ].Value, out thread );
long vss = 0;
long.TryParse ( m.Groups[ 5 ].Value, out vss );
long rss = 0;
long.TryParse ( m.Groups[ 6 ].Value, out rss );
string uid = m.Groups[ 7 ].Value.Trim ( );
string name = m.Groups[ 8 ].Value.Trim ( );

ProcessInfo pi = new ProcessInfo ( pid, name, thread, vss, rss, uid, cpu );
if ( TopProcessUpdated != null ) {
TopProcessUpdated ( this, new ProcessInfoEventArgs ( pi ) );
}
m = m.NextMatch ( );
}

if ( TopProcessUpdateComplete != null ) {
TopProcessUpdateComplete ( this, EventArgs.Empty );
}
};

TopProcess.ErrorDataReceived += delegate ( object sender, DataReceivedEventArgs e ) {

};

TopProcess.Exited += delegate ( object sender, EventArgs e ) {

};
TopProcess.Start ( );
TopProcess.BeginOutputReadLine ( );
TopProcess.BeginErrorReadLine ( );
}
} catch ( Exception ex ) {
this.LogError ( ex.Message, ex );
}
}*/

public void AdbProcessCleanUp ( ) {
Process[] procs = Process.GetProcessesByName ( "adb" );
foreach ( var item in procs ) {
try {
item.Kill ( );
} catch { }
}
}

/// <summary>
/// Determines whether [is app directory] [the specified path].
/// </summary>
/// <param name="path">The path.</param>
/// <returns>
/// 	<c>true</c> if [is app directory] [the specified path]; otherwise, <c>false</c>.
/// </returns>
public static bool IsAppDirectory ( string path ) {
return string.Compare ( path, SYSTEM_APP_PATH, false ) == 0 ||
string.Compare ( path, APP_PRIVATE_PATH, false ) == 0 ||
string.Compare ( path, APP_PUBLIC_PATH, false ) == 0 ||
string.Compare(path, APP_SD_PUBLIC_PATH, false) == 0 ||
string .Compare (path, APP_SD_PRIVATE_PATH, false ) == 0;
}

public string TempDataPath {
get { return System.IO.Path.Combine ( System.IO.Path.GetTempPath ( ), TEMP_DIRECTORY ); }
}

/// <summary>
/// Temps the path cleanup.
/// </summary>
public void TempPathCleanup ( ) {
string tempPath = System.IO.Path.Combine ( System.IO.Path.GetTempPath ( ), TEMP_DIRECTORY );
try {
if ( System.IO.Directory.Exists ( tempPath ) ) {
System.IO.Directory.Delete ( tempPath, true );
System.IO.Directory.CreateDirectory ( tempPath );
}
} catch ( Exception ex ) {
throw;
}
}

/// <summary>
/// Gets the adb version.
/// </summary>
/// <returns></returns>
/*public string GetAdbVersion ( ) {
try {
string data = RunAdbCommand ( string.Empty, AdbCommand.Version, string.Empty, true );

Regex regex = new Regex ( @"(\d{1,}\.\d{1,}\.\d{1,})", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline );
Match m = regex.Match ( data.Trim ( ) );
if ( m.Success ) {
return m.Groups[ 1 ].Value;
} else {
return string.Empty;
}
} catch ( DroidExplorer.Core.Exceptions.AdbException aex ) {
this.LogError ( aex.Message, aex );
return string.Empty;
} catch ( Exception ex ) {
this.LogError ( ex.Message, ex );
throw;
}
}*/

/// <summary>
/// Gets the aapt version.
/// </summary>
/// <returns></returns>
public string GetAaptVersion ( ) {
try {
string data = RunAaptCommand ( AaptCommand.Version, string.Empty );
Regex regex = new Regex ( @"(\d{1,}\.\d{1,}(\.\d{1,}\.\d{1,})?)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline );
Match m = regex.Match ( data );
if ( m.Success ) {
return m.Groups[ 1 ].Value;
} else {
return string.Empty;
}
} catch ( DroidExplorer.Core.Exceptions.AdbException aex ) {
this.LogError ( aex.Message, aex );
return string.Empty;
} catch ( Exception ex ) {
this.LogError ( ex.Message, ex );
throw;
}
}

/// <summary>
/// Flashes the image.
/// </summary>
/// <param name="device">The device.</param>
/// <param name="image">The image.</param>
public void FlashImage ( Device device, string image ) {
//ShellRun ( device, string.Format ( "flash_image recovery \"{0}\"", image ) );
device.ExecuteShellCommand ( String.Format ( "flash_image recovery \"{0}\"", image ),new ConsoleOutputReceiver() );
}

/// <summary>
/// Flashes the image.
/// </summary>
/// <param name="image">The image.</param>
public void FlashImage ( string image ) {
FlashImage ( this.DefaultDevice, image );
}

public void FastbootEraseRecovery ( Device device ) {
device.ExecuteShellCommand ( "fastboot erase recovery", new ConsoleOutputReceiver ( ) );

//ShellRun ( device, "fastboot erase recovery" );
}

/// <summary>
/// Uses Fastboots to erase recovery image.
/// </summary>
public void FastbootEraseRecovery ( ) {
FastbootEraseRecovery ( this.DefaultDevice );
}

public void FastbootFlashImage ( Device device, string image ) {
//ShellRun ( device, string.Format ( "fastboot flash recovery \"{0}\"", image ) );
device.ExecuteShellCommand ( string.Format ( "fastboot flash recovery \"{0}\"", image ), new ConsoleOutputReceiver ( ) );
}

public void FastbootFlashImage ( string image ) {
FastbootFlashImage ( this.DefaultDevice, image );
}

/// <summary>
/// Reboots the default device.
/// </summary>
public void Reboot ( ) {
//Reboot ( this.DefaultDevice );
this.DefaultDevice.Reboot ( );
}

/// <summary>
/// Reboots the specified device.
/// </summary>
/// <param name="device">The device.</param>
public void Reboot ( Device device ) {
//ShellRun ( device, "reboot" );
device.Reboot ( );
}

/// <summary>
/// Reboots in to recovery.
/// </summary>
/// <param name="device">The device.</param>
public void RebootRecovery ( Device device ) {
//ShellRun ( device, "reboot recovery" );
device.Reboot ( "recovery" );
}

/// <summary>
/// Reboots in to recovery.
/// </summary>
public void RebootRecovery ( ) {
RebootRecovery ( this.DefaultDevice );
}

/// <summary>
/// Applies the update.
/// </summary>
/// <param name="device">The device.</param>
public void ApplyUpdate ( Device device ) {
/*
mkdir -p /cache/recovery/
echo 'boot-recovery' >/cache/recovery/command
echo '--nandroid' >> /cache/recovery/command
echo '--update_package=SDCARD:update.zip' >> /cache/recovery/command
*/
device.ExecuteShellCommand ( "mkdir -p /cache/recovery/", new ConsoleOutputReceiver() );
device.ExecuteShellCommand ( "echo 'boot-recovery ' > /cache/recovery/command", new ConsoleOutputReceiver ( ) );
device.ExecuteShellCommand ( "echo '--update_package=SDCARD:update.zip' >> /cache/recovery/command", new ConsoleOutputReceiver ( ) );
RebootRecovery ( device );
}

/// <summary>
/// Applies the update.
/// </summary>
public void ApplyUpdate ( ) {
ApplyUpdate ( this.DefaultDevice );
}

/// <summary>
/// Gets the installed packages.
/// </summary>
/// <param name="device">The device.</param>
/// <returns></returns>
/*public PackageManagerListPackagesCommandResult GetInstalledPackages ( string device ) {
PackageManagerListPackagesCommandResult result = CommandRun ( device, AdbCommand.ShellPackageManager, "list packages -f" ) as PackageManagerListPackagesCommandResult;
return result;
}

/// <summary>
/// Gets the installed packages.
/// </summary>
/// <returns></returns>
public PackageManagerListPackagesCommandResult GetInstalledPackages ( ) {
return GetInstalledPackages ( this.DefaultDevice );
}

/// <summary>
/// Gets the installed packages apk information.
/// </summary>
/// <param name="device">The device.</param>
/// <returns></returns>
public List<AaptBrandingCommandResult> GetInstalledPackagesApkInformation ( string device ) {
PackageManagerListPackagesCommandResult result = GetInstalledPackages ( device );
List<AaptBrandingCommandResult> apkInfo = new List<AaptBrandingCommandResult> ( );
foreach ( var item in result.Packages.Keys ) {
AaptBrandingCommandResult ainfo = GetApkInformation ( result.Packages[ item ] );
ainfo.DevicePath = result.Packages[ item ];
if ( string.IsNullOrEmpty ( ainfo.Package ) ) {
ainfo.Package = item;
}
apkInfo.Add ( ainfo );
}
apkInfo.Sort ( new DroidExplorer.Core.Components.AaptBrandingCommandResultComparer ( ) );
return apkInfo;
}

/// <summary>
/// Gets the installed packages apk information.
/// </summary>
/// <returns></returns>
public List<AaptBrandingCommandResult> GetInstalledPackagesApkInformation ( ) {
return GetInstalledPackagesApkInformation ( this.DefaultDevice );
}

/// <summary>
/// Determines whether the specified package is installed on the device.
/// </summary>
/// <param name="device">The device.</param>
/// <param name="package">The package.</param>
/// <returns>
/// 	<c>true</c> if the specified package is installed on the device; otherwise, <c>false</c>.
/// </returns>
public bool IsPackageInstalled ( string device, string package ) {
GenericCommandResult gr = new GenericCommandResult ( RunAdbCommand ( device, AdbCommand.Shell, string.Format ( CultureInfo.InvariantCulture, "pm path {0}", package ) ) );

if ( gr.Output.Length > 0 ) {
return gr.Output.ToString ( ).StartsWith ( "package:" );
} else {
return false;
}

}

/// <summary>
/// Determines whether the specified package is installed on the default device.
/// </summary>
/// <param name="package">The package.</param>
/// <returns>
/// 	<c>true</c> if the specified package is installed on the default device; otherwise, <c>false</c>.
/// </returns>
public bool IsPackageInstalled ( string package ) {
return IsPackageInstalled ( this.DefaultDevice, package );
}

public AaptBrandingCommandResult GetApkInformation ( string apkFile ) {
System.IO.FileInfo lApk = PullFile ( apkFile );
if ( lApk == null || !lApk.Exists ) {
throw new System.IO.FileNotFoundException ( "File was not found on device.", System.IO.Path.GetFileName ( apkFile ) );
}

return GetLocalApkInformation ( lApk.FullName );
}

public AaptBrandingCommandResult GetApkInformationFromLocalCache ( String apkFile, String cacheDirectory ) {
string keyName = apkFile;
if ( keyName.StartsWith ( "/" ) ) {
keyName = keyName.Substring ( 1 );
}
keyName = keyName.Replace ( "/", "." );

// find if there is a local cache
System.IO.FileInfo lcache = new System.IO.FileInfo ( System.IO.Path.Combine ( cacheDirectory, String.Format ( "{0}.cache", keyName ) ) );
if ( lcache.Exists ) {
AaptBrandingCommandResult result = null;
XmlSerializer ser = new XmlSerializer ( typeof ( AaptBrandingCommandResult ) );
using ( System.IO.FileStream fs = new System.IO.FileStream ( lcache.FullName, System.IO.FileMode.Open, System.IO.FileAccess.Read ) ) {
result = ser.Deserialize ( fs ) as AaptBrandingCommandResult;
}

return result;
} else {
System.IO.FileInfo lApk = PullFile ( apkFile );
if ( lApk == null || !lApk.Exists ) {
throw new System.IO.FileNotFoundException ( "File was not found on device.", System.IO.Path.GetFileName ( apkFile ) );
}

AaptBrandingCommandResult result = GetApkInformation ( lApk.FullName );
XmlSerializer ser = new XmlSerializer ( typeof ( AaptBrandingCommandResult ) );
using ( System.IO.FileStream fs = new System.IO.FileStream ( lcache.FullName, System.IO.FileMode.Create, System.IO.FileAccess.Write ) ) {
ser.Serialize ( fs, result );
}
return result;
}
}

public AaptBrandingCommandResult GetLocalApkInformation ( string apkFile ) {
if ( string.IsNullOrEmpty ( apkFile ) || !System.IO.File.Exists ( apkFile ) ) {
throw new System.IO.FileNotFoundException ( "File was not found on device.", System.IO.Path.GetFileName ( apkFile ) );
}

AaptBrandingCommandResult result = AaptCommandRun ( AaptCommand.Dump_Badging, string.Format ( "\"{0}\"", apkFile ) ) as AaptBrandingCommandResult;
result.LocalApk = apkFile;
return result;
}

public List<string> GetApkPermissions ( string apkFile ) {
System.IO.FileInfo lApk = PullFile ( apkFile );
if ( lApk == null || !lApk.Exists ) {
throw new System.IO.FileNotFoundException ( "File was not found on device.", apkFile );
}

return GetLocalApkPermissions ( lApk.FullName );
}

public List<string> GetLocalApkPermissions ( string apkFile ) {
System.IO.FileInfo lApk = new System.IO.FileInfo ( apkFile );
if ( lApk == null || !lApk.Exists ) {
throw new System.IO.FileNotFoundException ( "File was not found on device.", apkFile );
}

AaptPermissionsCommandResult result = AaptCommandRun ( AaptCommand.Dump_Permissions, string.Format ( "\"{0}\"", apkFile ) ) as AaptPermissionsCommandResult;

if ( result != null ) {
return result.Permissions;
} else {
return null;
}
}

/// <summary>
/// Gets the apk icon image.
/// </summary>
/// <param name="apkFile">The apk file.</param>
/// <returns></returns>
public Image GetApkIconImage ( string apkFile ) {
System.IO.FileInfo lApk = PullFile ( apkFile );
if ( lApk == null || !lApk.Exists ) {
throw new System.IO.FileNotFoundException ( "File was not found on device.", System.IO.Path.GetFileName ( apkFile ) );
}

AaptBrandingCommandResult result = GetLocalApkInformation ( lApk.FullName );
result.LocalApk = lApk.FullName;

if ( !string.IsNullOrEmpty ( result.Icon ) ) {
string outPath = System.IO.Path.Combine ( lApk.Directory.FullName, System.IO.Path.GetFileNameWithoutExtension ( lApk.Name ) );
try {
ZipHelper.Unzip ( lApk.FullName, outPath, result.Icon, true, true );
} catch ( Exception ex ) {
this.LogError ( ex.Message, ex );
return null;
}
System.IO.FileInfo imageFile = new System.IO.FileInfo ( System.IO.Path.Combine ( outPath, System.IO.Path.GetFileName ( result.Icon ) ) );
if ( imageFile.Exists ) {
return Image.FromFile ( imageFile.FullName );
} else {
return null;
}
} else {
return null;
}
}

public Image GetLocalApkIconImage ( string apkFile ) {
System.IO.FileInfo lApk = new System.IO.FileInfo ( apkFile );
if ( lApk == null || !lApk.Exists ) {
throw new System.IO.FileNotFoundException ( "File was not found on device.", System.IO.Path.GetFileName ( apkFile ) );
}

AaptBrandingCommandResult result = GetLocalApkInformation ( lApk.FullName );
result.LocalApk = lApk.FullName;

if ( !string.IsNullOrEmpty ( result.Icon ) ) {
string outPath = System.IO.Path.Combine ( TempDataPath, System.IO.Path.GetFileNameWithoutExtension ( lApk.Name ) );
try {
ZipHelper.Unzip ( lApk.FullName, outPath, result.Icon, true, true );
} catch ( Exception ex ) {
this.LogError ( ex.Message, ex );
return null;
}
System.IO.FileInfo imageFile = new System.IO.FileInfo ( System.IO.Path.Combine ( outPath, System.IO.Path.GetFileName ( result.Icon ) ) );
if ( imageFile.Exists ) {
return Image.FromFile ( imageFile.FullName );
} else {
return null;
}
} else {
return null;
}
}

public Image GetApkIconImageFromCache ( string apkFile, String cacheDirectory ) {
string keyName = apkFile;
if ( keyName.StartsWith ( "/" ) ) {
keyName = keyName.Substring ( 1 );
}
keyName = keyName.Replace ( "/", "." );

// find if there is a local cache
System.IO.FileInfo lcache = new System.IO.FileInfo ( System.IO.Path.Combine ( cacheDirectory, String.Format ( "{0}.png", keyName ) ) );
if ( lcache.Exists ) {
return Image.FromFile ( lcache.FullName );
} else {
Image image = GetApkIconImage ( apkFile );
if ( image != null ) {
image.Save ( lcache.FullName, ImageFormat.Png );
}
return image;
}
}*/

/// <summary>
/// Launches the shell window.
/// </summary>
/// <param name="device">The device.</param>
public void LaunchShellWindow ( Device device ) {
LaunchShellWindow ( device, string.Empty );
}

/// <summary>
/// Launches the shell window.
/// </summary>
public void LaunchShellWindow ( ) {
LaunchShellWindow ( this.DefaultDevice );
}

/// <summary>
/// Launches the shell window.
/// </summary>
/// <param name="device">The device.</param>
/// <param name="initialCommand">The initial command.</param>
public void LaunchShellWindow( Device device, string initialCommand ) {
Process shell = new Process ( );
StringBuilder commandArg = new StringBuilder ( AdbCommandArguments ( device.SerialNumber, AdbCommand.Shell ) );
if ( !string.IsNullOrEmpty ( initialCommand ) ) {
commandArg.AppendFormat ( " {0}", initialCommand );
}
ProcessStartInfo psi = new ProcessStartInfo ( GetSdkTool ( AndroidDebugBridge.ADB ), commandArg.ToString ( ) );
psi.CreateNoWindow = false;
psi.ErrorDialog = true;
psi.WindowStyle = ProcessWindowStyle.Normal;
shell.StartInfo = psi;
shell.Start ( );
}

/// <summary>
/// Launches the redirected shell window.
/// </summary>
/// <param name="device">The device.</param>
/// <param name="initialCommand">The initial command.</param>
/// <param name="shellHandler">The shell handler.</param>
public void LaunchRedirectedShellWindow( Device device, string initialCommand, IShellProcess shellHandler ) {
new Thread ( new ThreadStart ( delegate ( ) {
Process shell = new Process ( );
StringBuilder commandArg = new StringBuilder ( AdbCommandArguments ( device.SerialNumber, AdbCommand.Shell ) );

shellHandler.SetBaseProcess ( shell );
ProcessStartInfo psi = new ProcessStartInfo ( GetSdkTool ( AndroidDebugBridge.ADB ), commandArg.ToString ( ) );
psi.CreateNoWindow = true;
psi.ErrorDialog = false;
psi.WindowStyle = ProcessWindowStyle.Hidden;

psi.UseShellExecute = false;
psi.RedirectStandardOutput =
psi.RedirectStandardInput =
psi.RedirectStandardError = true;

psi.StandardOutputEncoding = Encoding.UTF8;

shell.StartInfo = psi;
shell.Start ( );

if ( !string.IsNullOrEmpty ( initialCommand ) ) {
shell.StandardInput.WriteLine ( initialCommand );
}

shellHandler.SetInputStream ( shell.StandardInput );
shellHandler.SetOutputStream ( shell.StandardOutput );
shellHandler.SetErrorStream ( shell.StandardError );

shell.WaitForExit ( );

shellHandler.SetBaseProcess ( null );
} ) ).Start ( );
}

/// <summary>
/// Handles the OutputDataReceived event of the shell control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.Diagnostics.DataReceivedEventArgs"/> instance containing the event data.</param>
void shell_OutputDataReceived ( object sender, DataReceivedEventArgs e ) {
throw new NotImplementedException ( );
}

/// <summary>
/// Launches the hierarchy viewer.
/// </summary>
public void LaunchHierarchyViewer ( ) {
LaunchProcessWindow ( GetSdkTool ( AndroidDebugBridge.HIERARCHYVIEWER ), string.Empty, false );
}

/// <summary>
/// Launches the dalvik debug monitor.
/// </summary>
public void LaunchDalvikDebugMonitor ( ) {
LaunchProcessWindow ( GetSdkTool ( AndroidDebugBridge.DDMS ), string.Empty, false );
}

/// <summary>
/// Launches the process window.
/// </summary>
/// <param name="process">The process.</param>
/// <param name="args">The args.</param>
/// <param name="visible">if set to <c>true</c> [visible].</param>
public void LaunchProcessWindow( string process, string args, bool visible ) {
Process shell = new Process ( );
ProcessStartInfo psi = new ProcessStartInfo ( process, args );
psi.CreateNoWindow = !visible;
psi.ErrorDialog = visible;
psi.WindowStyle = visible ? ProcessWindowStyle.Normal : ProcessWindowStyle.Hidden;
shell.StartInfo = psi;
shell.Start ( );
}

/// <summary>
/// Gets the process ids.
/// </summary>
/// <returns></returns>
/*public List<int> GetProcessIds ( ) {
return GetProcessIds ( this.DefaultDevice );
}

/// <summary>
/// Gets the process info list.
/// </summary>
/// <param name="device">The device.</param>
/// <returns></returns>
public List<DroidExplorer.Core.IO.ProcessInfo> GetProcessInfoList ( string device ) {
List<DroidExplorer.Core.IO.ProcessInfo> procs = new List<DroidExplorer.Core.IO.ProcessInfo> ( );
foreach ( int pid in this.GetProcessIds ( device ) ) {
string data = ShellRun ( string.Format ( "ps {0}", pid ) ).Output.ToString ( );
procs.AddRange ( new ProcessInfoListCommandResult ( data ).Processes );
}
return procs;
}

/// <summary>
/// Gets the process info list.
/// </summary>
/// <returns></returns>
public List<DroidExplorer.Core.IO.ProcessInfo> GetProcessInfoList ( ) {
return GetProcessInfoList ( this.DefaultDevice );
}*/

/// <summary>
/// runs the command
/// </summary>
/// <param name="device">The device.</param>
/// <param name="command">The command.</param>
/// <param name="args">The args.</param>
/// <returns></returns>
/*private CommandResult CommandRun( Device device, AdbCommand command, string args ) {
switch ( command ) {
case AdbCommand.Devices:
return new DeviceListCommandResult ( RunAdbCommand ( device, command, args ) );
case AdbCommand.Help:
this.LogWarn ( "Help command not supported" );
return new GenericCommandResult ( "* help command not supported *" );
case AdbCommand.Root:
return new GenericCommandResult ( RunAdbCommand ( device, command, args ) );
case AdbCommand.Status_Window:
this.LogWarn ( "Status-Window command not supported" );
return new GenericCommandResult ( "* status window command not supported *" );
case AdbCommand.Wait_For_Device:
this.LogWarn ( "Wait-For-Device command not supported" );
return new GenericCommandResult ( "* wait for device command not supported *" );
case AdbCommand.ShellLS:
string path = args.Remove ( 0, Properties.Resources.ListDirectoryCommand.Trim ( ).Length - 4 ).Trim ( );
return new DirectoryListCommandResult ( RunAdbCommand ( device, AdbCommand.Shell, args ), path );
case AdbCommand.ShellPackageManager:
return new PackageManagerListPackagesCommandResult ( RunAdbCommand ( device, AdbCommand.Shell, string.Format ( "pm {0}", args ) ) );
case AdbCommand.Jdwp:
return new IntegerListCommandResult ( RunAdbCommand ( device, command, args ) );
case AdbCommand.Remount:
return new GenericCommandResult ( RunAdbCommand ( device, command, args, false ) );
case AdbCommand.Push:
case AdbCommand.Pull:
return new TransferCommandResult ( RunAdbCommand ( device, command, args ) );
case AdbCommand.Shell:
case AdbCommand.Get_SerialNo:
case AdbCommand.Version:
case AdbCommand.Get_State:
case AdbCommand.Uninstall:
case AdbCommand.Install:
return new GenericCommandResult ( RunAdbCommand ( device, command, args, true ) );
case AdbCommand.Start_Server:
case AdbCommand.Kill_Server:
return new GenericCommandResult ( RunAdbCommand ( device, command, args, false ) );
case AdbCommand.Bugreport:
case AdbCommand.Logcat:
case AdbCommand.Forward:
case AdbCommand.Emu:
case AdbCommand.Sync:
case AdbCommand.PPP:
this.LogWarn ( string.Format ( CultureInfo.InvariantCulture, "* {0} command not supported *", AdbCommandToString ( command ) ) );
return new GenericCommandResult ( string.Format ( CultureInfo.InvariantCulture, "* {0} command not supported *", AdbCommandToString ( command ) ) );
default:
this.LogWarn ( string.Format ( CultureInfo.InvariantCulture, "* unknown command ({0}) not supported *", AdbCommandToString ( command ) ) );
return new GenericCommandResult ( string.Format ( "* unknown command ({0}) not supported *", AdbCommandToString ( command ) ) );
}
}*/

/// <summary>
/// Runs the aapt command.
/// </summary>
/// <param name="command">The command.</param>
/// <param name="args">The args.</param>
/// <returns></returns>
private string RunAaptCommand ( AaptCommand command, string args ) {
//string localPath = System.IO.Path.GetDirectoryName ( typeof ( CommandRunner ).Assembly.Location );

StringBuilder result = new StringBuilder ( );
Process proc = new Process ( );
StringBuilder commandArg = new StringBuilder ( AaptCommandToString ( command ) );
if ( !string.IsNullOrEmpty ( args ) ) {
commandArg.AppendFormat ( " {0}", args );
}
ProcessStartInfo psi = new ProcessStartInfo ( GetSdkTool ( AndroidDebugBridge.AAPT ), commandArg.ToString ( ) );
this.LogDebug ( "{0} {1}", System.IO.Path.GetFileName ( psi.FileName ), psi.Arguments );

psi.CreateNoWindow = true;
psi.ErrorDialog = true;
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.WindowStyle = ProcessWindowStyle.Hidden;
proc.StartInfo = psi;
proc.OutputDataReceived += delegate ( object sender, DataReceivedEventArgs e ) {
if ( !string.IsNullOrEmpty ( e.Data ) ) {
result.AppendLine ( e.Data.Trim ( ) );
}
};

proc.ErrorDataReceived += delegate ( object sender, DataReceivedEventArgs e ) {
if ( !string.IsNullOrEmpty ( e.Data ) ) {
result.AppendLine ( e.Data.Trim ( ) );
}
};

proc.Exited += delegate ( object sender, EventArgs e ) {

};
proc.Start ( );
proc.BeginOutputReadLine ( );
proc.BeginErrorReadLine ( );
proc.WaitForExit ( );
return result.ToString ( );
}

private string RunAdbCommand( Device device, AdbCommand command, string args ) {
return RunAdbCommand ( device, command, args, true );
}

/// <summary>
/// Runs the adb command.
/// </summary>
/// <param name="device">The device.</param>
/// <param name="command">The command.</param>
/// <param name="args">The args.</param>
/// <returns></returns>
private string RunAdbCommand( Device device, AdbCommand command, string args, bool wait ) {
try {
StringBuilder result = new StringBuilder ( );
Process proc = new Process ( );
StringBuilder commandArg = new StringBuilder ( AdbCommandArguments ( device.SerialNumber, command ) );
if ( !string.IsNullOrEmpty ( args ) ) {
commandArg.AppendFormat ( " {0}", args );
}
ProcessStartInfo psi = new ProcessStartInfo ( GetSdkTool ( AndroidDebugBridge.ADB ), commandArg.ToString ( ) );
this.LogDebug ( "{0} {1}", System.IO.Path.GetFileName ( psi.FileName ), psi.Arguments );

psi.CreateNoWindow = true;
psi.ErrorDialog = false;
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.WindowStyle = ProcessWindowStyle.Hidden;
proc.StartInfo = psi;
proc.OutputDataReceived += delegate ( object sender, DataReceivedEventArgs e ) {
if ( !string.IsNullOrEmpty ( e.Data ) ) {
result.AppendLine ( e.Data.Trim ( ) );
}
};

proc.ErrorDataReceived += delegate ( object sender, DataReceivedEventArgs e ) {
if ( !string.IsNullOrEmpty ( e.Data ) ) {
result.AppendLine ( e.Data.Trim ( ) );
}
};

proc.Exited += delegate ( object sender, EventArgs e ) {

};
proc.Start ( );
proc.BeginOutputReadLine ( );
proc.BeginErrorReadLine ( );

if ( wait ) {
proc.WaitForExit ( );
} else {
Thread.Sleep ( 250 );
}

return result.ToString ( );
} catch ( Win32Exception wex ) {
this.LogError ( wex.Message, wex );
} catch ( Exception ex ) {
this.LogError ( ex.Message, ex );
}
return string.Empty;
}

/// <summary>
/// gets Adbs command arguments.
/// </summary>
/// <param name="device">The device.</param>
/// <param name="command">The command.</param>
/// <returns></returns>
private string AdbCommandArguments ( string device, AdbCommand command ) {
if ( string.IsNullOrEmpty ( device ) ) {
return AdbCommandToString ( command );
} else {
return string.Format ( "-s {0} {1}", device, AdbCommandToString ( command ) );
}
}

/// <summary>
/// Convert the Adb Command to the string value
/// </summary>
/// <param name="command">The command.</param>
/// <returns></returns>
private string AdbCommandToString ( AdbCommand command ) {
return command.ToString ( ).Replace ( "_", "-" ).ToLower ( );
}

/// <summary>
/// Convert the aapt Command to the string value
/// </summary>
/// <param name="command">The command.</param>
/// <returns></returns>
private string AaptCommandToString ( AaptCommand command ) {
return command.ToString ( ).Replace ( "_", " " ).ToLower ( );
}

/// <summary>
/// Gets the device state from the string value
/// </summary>
/// <param name="val">The val.</param>
/// <returns></returns>
private DeviceState StringToDeviceState ( string val ) {
try {
object o = Enum.Parse ( typeof ( DeviceState ), val, true );
if ( o == null ) {
return DeviceState.Unknown;
} else {
return (DeviceState)o;
}
} catch ( Exception ex ) {
return DeviceState.Unknown;
}

}

public static ISettings Settings { get; set; }

public static CommandRunner Instance {
get {
if ( _commandRunner == null ) {
_commandRunner = new CommandRunner ( );
}
return _commandRunner;
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: