You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

217 lines
7.1 KiB

using CoreAgent.Domain.Interfaces.System;
using CoreAgent.Domain.Interfaces.System.Command;
using CoreAgent.Domain.Models.System;
using Microsoft.Extensions.Logging;
namespace CoreAgent.Infrastructure.Services.System;
/// <summary>
/// 设备服务实现
/// </summary>
public class DeviceService : IDeviceService
{
private readonly ILogger<DeviceService> _logger;
private readonly ISystemCommandExecutor _commandExecutor;
public DeviceService(
ILogger<DeviceService> logger,
ISystemCommandExecutor commandExecutor)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_commandExecutor = commandExecutor ?? throw new ArgumentNullException(nameof(commandExecutor));
}
/// <summary>
/// 获取设备序列号(SN)
/// </summary>
/// <returns>设备信息</returns>
public async Task<DeviceInfo> GetSerialNumberAsync()
{
try
{
_logger.LogDebug("开始获取设备序列号");
// 根据操作系统选择不同的命令
string command = GetSerialNumberCommand();
var result = await _commandExecutor.ExecuteCommandAsync(command, new CancellationTokenSource(), 5000);
if (result.IsSuccess)
{
var serialNumber = ParseSerialNumber(result.Output);
if (serialNumber != null)
{
_logger.LogInformation("成功获取设备序列号: {SerialNumber}", serialNumber);
return new DeviceInfo
{
IsSuccess = true,
SerialNumber = serialNumber,
Timestamp = DateTime.UtcNow
};
}
else
{
_logger.LogWarning("解析设备序列号失败,输出内容: {Output}", result.Output);
return new DeviceInfo
{
IsSuccess = false,
SerialNumber = "UNKNOWN",
Timestamp = DateTime.UtcNow
};
}
}
else
{
_logger.LogError("获取设备序列号失败: {Error}", result.Error);
return new DeviceInfo
{
IsSuccess = false,
SerialNumber = "UNKNOWN",
Timestamp = DateTime.UtcNow
};
}
}
catch (Exception ex)
{
_logger.LogError(ex, "获取设备序列号时发生异常");
return new DeviceInfo
{
IsSuccess = false,
SerialNumber = "ERROR",
Timestamp = DateTime.UtcNow
};
}
}
/// <summary>
/// 获取设备序列号(SN)- 同步版本
/// </summary>
/// <returns>设备信息</returns>
public DeviceInfo GetSerialNumber()
{
try
{
_logger.LogDebug("开始获取设备序列号(同步)");
// 根据操作系统选择不同的命令
string command = GetSerialNumberCommand();
// 使用同步方式执行命令
var task = _commandExecutor.ExecuteCommandAsync(command, new CancellationTokenSource(), 5000);
task.Wait();
var result = task.Result;
if (result.IsSuccess)
{
var serialNumber = ParseSerialNumber(result.Output);
if (serialNumber != null)
{
_logger.LogInformation("成功获取设备序列号: {SerialNumber}", serialNumber);
return new DeviceInfo
{
IsSuccess = true,
SerialNumber = serialNumber,
Timestamp = DateTime.UtcNow
};
}
else
{
_logger.LogWarning("解析设备序列号失败,输出内容: {Output}", result.Output);
return new DeviceInfo
{
IsSuccess = false,
SerialNumber = "UNKNOWN",
Timestamp = DateTime.UtcNow
};
}
}
else
{
_logger.LogError("获取设备序列号失败: {Error}", result.Error);
return new DeviceInfo
{
IsSuccess = false,
SerialNumber = "UNKNOWN",
Timestamp = DateTime.UtcNow
};
}
}
catch (Exception ex)
{
_logger.LogError(ex, "获取设备序列号时发生异常");
return new DeviceInfo
{
IsSuccess = false,
SerialNumber = "ERROR",
Timestamp = DateTime.UtcNow
};
}
}
/// <summary>
/// 根据操作系统获取序列号命令
/// </summary>
/// <returns>命令字符串</returns>
private string GetSerialNumberCommand()
{
if (OperatingSystem.IsWindows())
{
// Windows系统获取序列号命令
return "wmic bios get serialnumber /value";
}
else if (OperatingSystem.IsLinux())
{
// Linux系统获取序列号命令
return "smartctl -i /dev/nvme0n1|grep Serial";
}
else
{
// 其他系统使用通用命令
return "echo UNKNOWN";
}
}
/// <summary>
/// 解析序列号输出
/// </summary>
/// <param name="output">命令输出</param>
/// <returns>解析后的序列号,失败时返回null</returns>
private string? ParseSerialNumber(string output)
{
if (string.IsNullOrWhiteSpace(output))
{
return null;
}
// 清理输出内容
var lines = output.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
var trimmedLine = line.Trim();
if (OperatingSystem.IsWindows())
{
// Windows输出格式: SerialNumber=XXXXXXXX
if (trimmedLine.StartsWith("SerialNumber=", StringComparison.OrdinalIgnoreCase))
{
var serialNumber = trimmedLine.Substring("SerialNumber=".Length).Trim();
return string.IsNullOrWhiteSpace(serialNumber) ? null : serialNumber;
}
}
else if (OperatingSystem.IsLinux())
{
// Linux输出格式: Serial Number: xxxxxxxx
if (trimmedLine.StartsWith("Serial Number:", StringComparison.OrdinalIgnoreCase))
{
var serialNumber = trimmedLine.Substring("Serial Number:".Length).Trim();
return string.IsNullOrWhiteSpace(serialNumber) ? null : serialNumber;
}
}
}
return null;
}
}