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
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;
|
|
}
|
|
}
|