云算力平台windows桌面应用

This commit is contained in:
lzx
2026-01-22 15:14:27 +08:00
commit 1fe0e54138
52 changed files with 5447 additions and 0 deletions

198
lib/core/system_info.dart Normal file
View File

@@ -0,0 +1,198 @@
import 'dart:io';
import 'package:logging/logging.dart';
import '../models/client_status.dart';
import '../utils/path_utils.dart';
/// 系统信息获取服务
class SystemInfoService {
static final SystemInfoService _instance = SystemInfoService._internal();
factory SystemInfoService() => _instance;
SystemInfoService._internal();
final Logger _logger = Logger('SystemInfoService');
/// 获取机器码(使用硬盘序列号)
Future<String> getMachineCode() async {
try {
if (Platform.isWindows) {
// 延迟执行,避免启动时崩溃
await Future.delayed(const Duration(seconds: 3));
// 使用 wmic 获取硬盘序列号
try {
final result = await Process.run(
'wmic',
['diskdrive', 'get', 'serialnumber'],
runInShell: true,
);
if (result.exitCode == 0) {
final output = result.stdout.toString();
final lines = output.split('\n');
// 查找序列号(跳过标题行)
for (final line in lines) {
final trimmed = line.trim();
if (trimmed.isNotEmpty &&
!trimmed.toLowerCase().contains('serialnumber') &&
trimmed != '') {
// 提取序列号(去除空格)
final serial = trimmed.replaceAll(RegExp(r'\s+'), '');
if (serial.isNotEmpty) {
_logger.info('获取到硬盘序列号: $serial');
return serial;
}
}
}
}
_logger.warning('wmic 命令执行成功但未找到有效序列号');
} catch (e) {
_logger.warning('使用 wmic 获取硬盘序列号失败: $e');
}
// 备用方案:使用环境变量生成标识符
final computerName = Platform.environment['COMPUTERNAME'] ?? 'UNKNOWN';
final userName = Platform.environment['USERNAME'] ?? 'UNKNOWN';
final userProfile = Platform.environment['USERPROFILE'] ?? '';
final identifier = '${computerName}_${userName}_${userProfile.hashCode.abs()}';
_logger.info('使用备用标识符作为机器码: $identifier');
return identifier;
}
// 非 Windows 系统
_logger.warning('无法获取机器码,使用临时标识');
return 'UNKNOWN_${DateTime.now().millisecondsSinceEpoch}';
} catch (e) {
_logger.severe('获取机器码失败: $e');
// 不抛出异常,返回临时标识
return 'ERROR_${DateTime.now().millisecondsSinceEpoch}';
}
}
/// 获取GPU信息仅在启动时调用一次
Future<List<GPUInfo>> getGPUInfo() async {
try {
// 使用 nvidia-smi 获取GPU信息
final result = await Process.run(
'nvidia-smi',
['--query-gpu=index,name,memory.total', '--format=csv,noheader,nounits'],
runInShell: true,
).timeout(
const Duration(seconds: 10),
onTimeout: () {
_logger.warning('nvidia-smi 执行超时');
return ProcessResult(0, -1, '', 'timeout');
},
);
if (result.exitCode != 0) {
_logger.warning('nvidia-smi 执行失败: exitCode=${result.exitCode}, stderr=${result.stderr}');
return [];
}
final output = result.stdout.toString().trim();
if (output.isEmpty) {
_logger.info('nvidia-smi 返回空输出未检测到GPU');
return [];
}
final lines = output.split('\n');
final gpus = <GPUInfo>[];
for (final line in lines) {
if (line.trim().isEmpty) continue;
final parts = line.split(', ');
if (parts.length >= 3) {
try {
final index = int.parse(parts[0].trim());
final model = parts[1].trim();
final memoryStr = parts[2].trim();
final memory = double.tryParse(memoryStr) ?? 0;
gpus.add(GPUInfo(
index: index,
brand: 'NVIDIA',
model: model,
memory: memory,
));
_logger.info('检测到GPU: 索引=$index, 型号=$model, 显存=${memory}MB');
} catch (e) {
_logger.warning('解析GPU信息失败: $line, 错误: $e');
}
}
}
if (gpus.isEmpty) {
_logger.info('未检测到GPU');
} else {
_logger.info('成功获取 ${gpus.length} 个GPU信息');
}
return gpus;
} catch (e) {
_logger.warning('获取GPU信息失败: $e');
// 不抛出异常返回空列表UI会显示"未检测到GPU"
return [];
}
}
/// 读取版本号(从根目录 bin/version 文件)
Future<String> getVersion() async {
try {
final versionPath = PathUtils.binFile('version');
final file = File(versionPath);
if (await file.exists()) {
final content = await file.readAsString();
return content.trim();
} else {
_logger.warning('版本文件不存在: $versionPath');
}
} catch (e) {
_logger.warning('读取版本号失败: $e');
}
return '未知版本';
}
/// 读取身份信息(从根目录 bin/auth 文件)
Future<String> getAuth() async {
try {
final authPath = PathUtils.binFile('auth');
final file = File(authPath);
if (await file.exists()) {
final content = await file.readAsString();
return content.trim();
} else {
_logger.warning('身份文件不存在: $authPath');
}
} catch (e) {
_logger.warning('读取身份信息失败: $e');
}
return '未配置';
}
/// 检查管理员权限Windows
Future<bool> checkAdminPermission() async {
if (!Platform.isWindows) {
return true;
}
try {
// 由于 Process.run 会导致崩溃,这里使用环境变量判断
// 如果存在管理员相关的环境变量,可能具有管理员权限
// 这是一个简化的判断,可能不准确,但不会崩溃
final userProfile = Platform.environment['USERPROFILE'];
if (userProfile != null && userProfile.contains('Administrator')) {
return true;
}
// 默认返回 false表示可能没有管理员权限
_logger.info('无法准确检测管理员权限(避免 Process.run 崩溃),返回 false');
return false;
} catch (e) {
_logger.warning('检查管理员权限失败: $e');
return false;
}
}
}