using CliWrap; using CliWrap.Buffered; using CoreAgent.Domain.Interfaces.System.Command; using CoreAgent.Domain.Models; using CoreAgent.Domain.Models.System; using Microsoft.Extensions.Logging; namespace CoreAgent.Infrastructure.Command.Base; /// /// 命令执行器基类 /// public abstract class BaseCommandExecutor : ISystemCommandExecutor { protected readonly ILogger _logger; protected abstract string DefaultShell { get; } protected BaseCommandExecutor(ILogger logger) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } /// /// 执行命令并实时输出结果 /// public abstract Task ExecuteCommandWithOutputAsync(string command, Action outputHandler, Action errorHandler, CancellationTokenSource cancellationTokenSource, int timeout = -1); /// /// 执行命令并返回结果 /// public abstract Task ExecuteCommandAsync(string command, CancellationTokenSource cancellationTokenSource, int timeout = -1); /// /// 获取命令参数,由子类实现具体的命令参数格式化逻辑 /// protected abstract string GetCommandArguments(string command); /// /// 执行命令的通用逻辑 /// protected virtual async Task ExecuteCommandInternalAsync(string command, string arguments, CancellationTokenSource cancellationTokenSource, int timeout = -1) { if (string.IsNullOrWhiteSpace(command)) { throw new ArgumentException("命令不能为空", nameof(command)); } if (cancellationTokenSource == null) { throw new ArgumentNullException(nameof(cancellationTokenSource)); } var startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); try { _logger.LogDebug("开始执行命令: {Command}", command); var cmd = Cli.Wrap(DefaultShell) .WithArguments(arguments) .WithValidation(CommandResultValidation.None); // 如果设置了超时,创建一个新的 CancellationTokenSource using var timeoutCts = timeout > 0 ? new CancellationTokenSource(timeout) : null; using var linkedCts = timeout > 0 ? CancellationTokenSource.CreateLinkedTokenSource(cancellationTokenSource.Token, timeoutCts!.Token) : cancellationTokenSource; var result = await cmd.ExecuteBufferedAsync(linkedCts.Token); var executionTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - startTime; if (result.IsSuccess) { _logger.LogDebug("命令执行成功 - 输出: {Output}", result.StandardOutput); return CommandExecutionResult.Success(result.StandardOutput, executionTime); } else { _logger.LogDebug("命令执行失败 - 错误: {Error}", result.StandardError); return CommandExecutionResult.Failure(result.StandardError, executionTime); } } catch (OperationCanceledException ex) { var executionTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - startTime; _logger.LogError(ex, "命令执行超时: {Command}", command); return CommandExecutionResult.Failure("命令执行超时", executionTime); } catch (Exception ex) { var executionTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - startTime; _logger.LogError(ex, "命令执行失败: {Command}, 错误: {ErrorMessage}", command, ex.Message); return CommandExecutionResult.Failure(ex.Message, executionTime); } } }