欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > c# 企业级ADB通信示例

c# 企业级ADB通信示例

2025/5/14 22:12:05 来源:https://blog.csdn.net/weixin_44291381/article/details/147069774  浏览:    关键词:c# 企业级ADB通信示例
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace ADB_Demo
{/// <summary>/// ADB管理器,提供与Android设备的通信功能/// </summary>public class AdbManager : IDisposable{private readonly string _adbPath;private readonly Dictionary<string, Process> _runningProcesses = new();private readonly object _processLock = new();private bool _disposed;/// <summary>/// ADB管理器构造函数/// </summary>/// <param name="adbPath">ADB可执行文件路径,默认自动查找</param>public AdbManager(string adbPath = null){_adbPath = FindAdbPath(adbPath);if (string.IsNullOrEmpty(_adbPath))throw new FileNotFoundException("ADB executable not found");}private string FindAdbPath(string customPath){if (!string.IsNullOrEmpty(customPath) && File.Exists(customPath))return Path.GetFullPath(customPath);// 查找环境变量中的adbvar paths = Environment.GetEnvironmentVariable("PATH")?.Split(Path.PathSeparator) ?? Array.Empty<string>();foreach (var path in paths){try{var fullPath = Path.Combine(path, "adb.exe");if (File.Exists(fullPath))return fullPath;}catch{// 忽略无效路径}}// 尝试Android SDK默认位置var sdkPaths = new[]{Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Android", "android-sdk", "platform-tools", "adb.exe"),Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "AppData", "Local", "Android", "Sdk", "platform-tools", "adb.exe")};return sdkPaths.FirstOrDefault(File.Exists);}/// <summary>/// 执行ADB命令并返回结果/// </summary>public async Task<AdbCommandResult> ExecuteCommandAsync(string command,CancellationToken cancellationToken = default,int timeoutMilliseconds = 30000){if (_disposed)throw new ObjectDisposedException(nameof(AdbManager));var processInfo = new ProcessStartInfo{FileName = _adbPath,Arguments = command,RedirectStandardOutput = true,RedirectStandardError = true,UseShellExecute = false,CreateNoWindow = true,StandardOutputEncoding = System.Text.Encoding.UTF8,StandardErrorEncoding = System.Text.Encoding.UTF8};var process = new Process { StartInfo = processInfo };var processId = Guid.NewGuid().ToString();lock (_processLock){_runningProcesses.Add(processId, process);}try{process.Start();process.BeginOutputReadLine();process.BeginErrorReadLine();var outputBuilder = new System.Text.StringBuilder();var errorBuilder = new System.Text.StringBuilder();process.OutputDataReceived += (_, e) => { if (e.Data != null) outputBuilder.AppendLine(e.Data); };process.ErrorDataReceived += (_, e) => { if (e.Data != null) errorBuilder.AppendLine(e.Data); };// 等待进程退出或超时var processTask = Task.Run(() => process.WaitForExit(), cancellationToken);var completedTask = await Task.WhenAny(processTask, Task.Delay(timeoutMilliseconds, cancellationToken));if (completedTask != processTask){throw new TimeoutException($"ADB command timed out after {timeoutMilliseconds}ms");}if (process.ExitCode != 0){throw new AdbCommandException($"ADB command failed with exit code {process.ExitCode}",errorBuilder.ToString(), process.ExitCode);}return new AdbCommandResult(outputBuilder.ToString().Trim(), errorBuilder.ToString().Trim());}finally{lock (_processLock){_runningProcesses.Remove(processId);}if (!process.HasExited){process.Kill();}process.Dispose();}}/// <summary>/// 获取连接的设备列表/// </summary>public async Task<List<AdbDevice>> GetDevicesAsync(CancellationToken cancellationToken = default){var result = await ExecuteCommandAsync("devices -l", cancellationToken);var lines = result.Output.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);// 跳过第一行标题行return lines.Skip(1).Select(line => line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)).Where(parts => parts.Length >= 2).Select(parts => new AdbDevice{SerialNumber = parts[0],Status = parts[1],Properties = parts.Skip(2).Select(p => p.Split(':')).Where(p => p.Length == 2).ToDictionary(p => p[0], p => p[1])}).ToList();}/// <summary>/// 停止所有正在运行的ADB进程/// </summary>public void StopAllProcesses(){lock (_processLock){foreach (var process in _runningProcesses.Values){try{if (!process.HasExited){process.Kill();}}catch{// 忽略停止过程中的错误}}_runningProcesses.Clear();}}public void Dispose(){if (_disposed) return;StopAllProcesses();_disposed = true;GC.SuppressFinalize(this);}~AdbManager(){Dispose();}}/// <summary>/// ADB命令执行结果/// </summary>public class AdbCommandResult{public string Output { get; }public string Error { get; }public AdbCommandResult(string output, string error){Output = output;Error = error;}}/// <summary>/// ADB设备信息/// </summary>public class AdbDevice{public string SerialNumber { get; set; }public string Status { get; set; }public Dictionary<string, string> Properties { get; set; } = new();public override string ToString() => $"{SerialNumber} ({Status})";}/// <summary>/// ADB命令异常/// </summary>public class AdbCommandException : Exception{public string ErrorOutput { get; }public int ExitCode { get; }public AdbCommandException(string message, string errorOutput, int exitCode): base(message){ErrorOutput = errorOutput;ExitCode = exitCode;}}
}

应用示例:

namespace ADB_Demo
{internal class Program{static async Task Main(string[] args){using var adb = new AdbManager();var ret = await adb.ExecuteCommandAsync("version");// 1. 获取设备列表var devices = await adb.GetDevicesAsync();Console.WriteLine("Connected devices:");foreach (var device in devices){Console.WriteLine($"- {device.SerialNumber} ({device.Status})");}}}
}

各函数的功能说明:


AdbManager 类

1. 构造函数 AdbManager(string adbPath = null)

功能:初始化 ADB 管理器,自动查找或使用指定的 ADB 可执行文件路径。
参数
adbPath:可选,自定义 ADB 路径。若未提供,则自动搜索。

2. FindAdbPath(string customPath)(私有方法)

功能:查找 ADB 可执行文件的完整路径。
查找顺序

  1. 优先使用 customPath(如果有效)。
  2. 搜索系统 PATH 环境变量。
  3. 检查 Android SDK 默认安装路径(Windows 平台)。
3. ExecuteCommandAsync(string command, CancellationToken cancellationToken = default, int timeoutMilliseconds = 30000)

功能:异步执行指定的 ADB 命令,并返回输出结果。
参数
command:要执行的 ADB 命令(如 "devices -l")。
cancellationToken:支持取消操作。
timeoutMilliseconds:超时时间(默认 30 秒)。
返回值AdbCommandResult,包含标准输出和错误输出。

4. GetDevicesAsync(CancellationToken cancellationToken = default)

功能:获取当前连接的 Android 设备列表。
实现:调用 adb devices -l 并解析输出。
返回值List<AdbDevice>,包含设备序列号、状态和属性(如 model)。

5. StopAllProcesses()

功能:强制终止所有正在运行的 ADB 进程。
用途:通常在释放资源时调用。

6. Dispose() 和析构函数 ~AdbManager()

功能:实现 IDisposable 接口,清理资源(停止所有进程)。


辅助类

1. AdbCommandResult

功能:封装 ADB 命令的执行结果。
属性
Output:标准输出内容。
Error:错误输出内容。

2. AdbDevice

功能:表示一个连接的 Android 设备。
属性
SerialNumber:设备序列号(如 emulator-5554)。
Status:设备状态(如 device/offline)。
Properties:设备属性字典(如 model:Android_SDK_built_for_x86)。

3. AdbCommandException

功能:自定义异常,表示 ADB 命令执行失败。
属性
ErrorOutput:错误输出内容。
ExitCode:进程退出码。


版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词