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 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> 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 = []; 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 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 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 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; } } }