import 'dart:io'; import 'package:hive_ce/hive.dart'; import 'package:starcitizen_doctor/common/utils/log.dart'; import 'package:starcitizen_doctor/common/rust/api/win32_api.dart' as win32; class SystemHelper { static Future checkNvmePatchStatus() async { try { return await win32.checkNvmePatchStatus(); } catch (e) { dPrint("checkNvmePatchStatus error: $e"); return false; } } static Future addNvmePatch() async { try { await win32.addNvmePatch(); return ""; } catch (e) { dPrint("addNvmePatch error: $e"); return e.toString(); } } static Future doRemoveNvmePath() async { try { await win32.removeNvmePatch(); return true; } catch (e) { dPrint("doRemoveNvmePath error: $e"); return false; } } /// 获取 RSI 启动器 目录 static Future getRSILauncherPath({bool skipEXE = false}) async { final confBox = await Hive.openBox("app_conf"); final path = confBox.get("custom_launcher_path"); if (path != null && path != "") { if (await File(path).exists()) { if (skipEXE) { return "${path.toString().replaceAll("\\RSI Launcher.exe", "")}\\"; } return path; } } Map envVars = Platform.environment; final programDataPath = envVars["programdata"]; final rsiFilePath = "$programDataPath\\Microsoft\\Windows\\Start Menu\\Programs\\Roberts Space Industries\\RSI Launcher.lnk"; final rsiLinkFile = File(rsiFilePath); if (await rsiLinkFile.exists()) { try { final targetPath = await win32.resolveShortcut(lnkPath: rsiFilePath); if (targetPath.contains("RSI Launcher.exe")) { final start = targetPath.split("RSI Launcher.exe"); if (skipEXE) { return start[0]; } return "${start[0]}RSI Launcher.exe"; } } catch (e) { dPrint("resolveShortcut error: $e"); } } return ""; } static Future killRSILauncher() async { var pList = await getPID("RSI Launcher"); for (var pid in pList) { try { Process.killPid(pid); } catch (e) { dPrint("killRSILauncher Error: $e"); } } } static Future> getPID(String name) async { try { final pList = await win32.getProcessListByName(processName: name); return pList.map((e) => e.pid).toList(); } catch (e) { dPrint("getPID Error: $e"); return []; } } static Future checkAndLaunchRSILauncher(String path) async { // check running and kill await killRSILauncher(); // launch final processorAffinity = await SystemHelper.getCpuAffinity(); if (processorAffinity == null) { Process.run(path, []); } else { Process.run("cmd.exe", ['/C', 'Start', '""', '/High', '/Affinity', processorAffinity, path]); } dPrint(path); } static Future getSystemMemorySizeGB() async { try { final memoryGb = await win32.getSystemMemorySizeGb(); return memoryGb.toInt(); } catch (e) { dPrint("getSystemMemorySizeGB error: $e"); return 0; } } static Future getSystemCimInstance(String win32InstanceName, {pathName = "Name"}) async { // This method is deprecated, use getSystemInfo() instead try { final sysInfo = await win32.getSystemInfo(); if (win32InstanceName.contains("OperatingSystem")) { return sysInfo.osName; } else if (win32InstanceName.contains("Processor")) { return sysInfo.cpuName; } else if (win32InstanceName.contains("VideoController")) { return sysInfo.gpuInfo; } else if (win32InstanceName.contains("DiskDrive")) { return sysInfo.diskInfo; } } catch (e) { dPrint("getSystemCimInstance error: $e"); } return ""; } static Future getSystemName() async { try { final sysInfo = await win32.getSystemInfo(); return sysInfo.osName; } catch (e) { dPrint("getSystemName error: $e"); return ""; } } static Future getCpuName() async { try { final sysInfo = await win32.getSystemInfo(); return sysInfo.cpuName; } catch (e) { dPrint("getCpuName error: $e"); return ""; } } static Future getGpuInfo() async { try { // Try registry first for more accurate VRAM info final regInfo = await win32.getGpuInfoFromRegistry(); if (regInfo.isNotEmpty) { return regInfo; } // Fallback to WMI final sysInfo = await win32.getSystemInfo(); return sysInfo.gpuInfo; } catch (e) { dPrint("getGpuInfo error: $e"); return ""; } } static Future getDiskInfo() async { try { final sysInfo = await win32.getSystemInfo(); return sysInfo.diskInfo; } catch (e) { dPrint("getDiskInfo error: $e"); return ""; } } static Future getDirLen(String path, {List? skipPath}) async { if (path == "") return 0; int totalSize = 0; try { final l = await Directory(path).list(recursive: true).toList(); for (var element in l) { if (element is File) { bool skip = false; if (skipPath != null) { for (var value in skipPath) { if (element.absolute.path.startsWith(value)) { skip = true; break; } } } if (!skip) totalSize += await element.length(); } } } catch (_) {} return totalSize; } static Future getNumberOfLogicalProcessors() async { try { return await win32.getNumberOfLogicalProcessors(); } catch (e) { dPrint("getNumberOfLogicalProcessors error: $e"); return 0; } } static Future getCpuAffinity() async { final confBox = await Hive.openBox("app_conf"); final eCoreCount = int.tryParse(confBox.get("gameLaunch_eCore_count", defaultValue: "0")) ?? 0; final cpuNumber = await getNumberOfLogicalProcessors(); if (cpuNumber == 0 || eCoreCount == 0 || eCoreCount > cpuNumber) { return null; } StringBuffer sb = StringBuffer(); for (var i = 0; i < cpuNumber; i++) { if (i < eCoreCount) { sb.write("0"); } else { sb.write("1"); } } final binaryString = sb.toString(); int hexDigits = (binaryString.length / 4).ceil(); dPrint("Affinity sb ==== $sb"); return int.parse(binaryString, radix: 2).toRadixString(16).padLeft(hexDigits, '0').toUpperCase(); } static Future openDir(dynamic path, {bool isFile = false}) async { dPrint("SystemHelper.openDir path === $path"); if (Platform.isWindows) { try { await win32.openDirWithExplorer(path: path.toString(), isFile: isFile); } catch (e) { dPrint("openDir error: $e"); } } } static String getHostsFilePath() { if (Platform.isWindows) { final envVars = Platform.environment; final systemRoot = envVars["SYSTEMROOT"]; return "$systemRoot\\System32\\drivers\\etc\\hosts"; } return "/etc/hosts"; } }