From bba8acfe76a0571d214eefbfa6f86b69b2e82263 Mon Sep 17 00:00:00 2001 From: Rust Date: Wed, 29 Oct 2025 16:50:11 +0800 Subject: [PATCH] =?UTF-8?q?windows=E8=B7=AF=E5=BE=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit e226b8635d60a8c2fea8a99c151a5161a797aa52) --- .../services/singbox_imp/kr_sing_box_imp.dart | 162 ++++++++---------- 1 file changed, 71 insertions(+), 91 deletions(-) diff --git a/lib/app/services/singbox_imp/kr_sing_box_imp.dart b/lib/app/services/singbox_imp/kr_sing_box_imp.dart index 271ca71..a951958 100755 --- a/lib/app/services/singbox_imp/kr_sing_box_imp.dart +++ b/lib/app/services/singbox_imp/kr_sing_box_imp.dart @@ -320,13 +320,45 @@ class KRSingBoxImp { KRLogUtil.kr_e('❌ setup() 前最终验证失败: $e', tag: 'SingBox'); // 不抛出异常,让 setup() 自己处理 } - - if (!directory.existsSync()) { - await directory.create(recursive: true); - KRLogUtil.kr_i('已创建 configs 目录', tag: 'SingBox'); - } - KRLogUtil.kr_i('目录创建完成', tag: 'SingBox'); + final configsDir = Directory(p.join(kr_configDics.workingDir.path, "configs")); + if (!configsDir.existsSync()) { + try { + await configsDir.create(recursive: true); + KRLogUtil.kr_i('✅ 已创建 configs 目录: ${configsDir.path}', tag: 'SingBox'); + } catch (e) { + KRLogUtil.kr_e('⚠️ configs 目录创建失败: $e', tag: 'SingBox'); + // 不抛出异常,继续初始化 + } + } else { + KRLogUtil.kr_i('✅ configs 目录已存在: ${configsDir.path}', tag: 'SingBox'); + } + + // 特别处理 extensionData.db 文件 (Windows特定) + if (Platform.isWindows) { + try { + final extensionDataDbPath = p.join(finalDataDir.path, 'extensionData.db'); + KRLogUtil.kr_i('👉 准备处理 extensionData.db 路径: $extensionDataDbPath', tag: 'SingBox'); + + // 确保 extensionData.db 的父目录存在 + final extensionDataParent = Directory(p.dirname(extensionDataDbPath)); + if (!extensionDataParent.existsSync()) { + await extensionDataParent.create(recursive: true); + KRLogUtil.kr_i('✅ 已创建 extensionData.db 父目录', tag: 'SingBox'); + } + + // 测试文件创建权限 + final testFile = File(p.join(extensionDataParent.path, '.test_extension')); + await testFile.writeAsString('test'); + await testFile.delete(); + KRLogUtil.kr_i('✅ extensionData 目录权限验证通过', tag: 'SingBox'); + } catch (e) { + KRLogUtil.kr_e('⚠️ extensionData 目录处理失败: $e', tag: 'SingBox'); + // 不抛出异常,继续初始化 + } + } + + KRLogUtil.kr_i('✅ 目录创建完成', tag: 'SingBox'); KRLogUtil.kr_i('开始设置 SingBox', tag: 'SingBox'); KRLogUtil.kr_i(' - baseDir: ${kr_configDics.baseDir.path}', tag: 'SingBox'); KRLogUtil.kr_i(' - workingDir: ${kr_configDics.workingDir.path}', tag: 'SingBox'); @@ -363,94 +395,42 @@ class KRSingBoxImp { KRLogUtil.kr_e('⚠️ 路径格式可能需要规范化: $workingPath -> $normalizedPath', tag: 'SingBox'); } } - - await kr_singBox.setup(kr_configDics, false).map((r) { - KRLogUtil.kr_i('✅ SingBox setup() 调用成功', tag: 'SingBox'); - - // setup() 返回成功,但可能数据库初始化还在进行中 - // 在 Windows 上额外等待,确保 libcore 内部的服务初始化完成 - if (Platform.isWindows) { - KRLogUtil.kr_i('⏳ Windows: 等待 libcore 服务初始化完成...', tag: 'SingBox'); - } - return r; - }).mapLeft((err) { - KRLogUtil.kr_e('❌ SingBox setup() 调用失败: $err', tag: 'SingBox'); - KRLogUtil.kr_e('诊断信息:', tag: 'SingBox'); - KRLogUtil.kr_e(' - workingDir: ${kr_configDics.workingDir.path}', tag: 'SingBox'); - KRLogUtil.kr_e(' - workingDir 存在: ${kr_configDics.workingDir.existsSync()}', tag: 'SingBox'); - KRLogUtil.kr_e(' - data 目录绝对路径: ${p.join(kr_configDics.workingDir.path, "data")}', tag: 'SingBox'); - KRLogUtil.kr_e(' - data 目录存在: ${finalDataDir.existsSync()}', tag: 'SingBox'); - if (finalDataDir.existsSync()) { - try { - final files = finalDataDir.listSync(); - KRLogUtil.kr_e(' - data 目录文件数量: ${files.length}', tag: 'SingBox'); - } catch (e) { - KRLogUtil.kr_e(' - 无法列出 data 目录: $e', tag: 'SingBox'); - } - } - throw err; - }).run(); - - // setup() 成功后的额外等待(Windows 上数据库初始化可能需要时间) - if (Platform.isWindows) { - await Future.delayed(const Duration(milliseconds: 500)); - KRLogUtil.kr_i('⏳ Windows: libcore 初始化等待完成', tag: 'SingBox'); - } - KRLogUtil.kr_i('开始更新 SingBox 选项'); - KRLogUtil.kr_i('📋 SingBox 配置选项: ${oOption.toJson()}', tag: 'SingBox'); - await kr_singBox.changeOptions(oOption) - ..map((r) { - KRLogUtil.kr_i('✅ SingBox 选项更新成功', tag: 'SingBox'); - }).mapLeft((err) { - KRLogUtil.kr_e('❌ SingBox 选项更新失败: $err', tag: 'SingBox'); - throw err; - }).run(); - - KRLogUtil.kr_i('开始监听状态'); - // 初始订阅状态流 - kr_singBox.watchStatus().listen((status) { - KRLogUtil.kr_i('🔄 SingBox 状态变化: $status', tag: 'SingBox'); - KRLogUtil.kr_i('📊 状态类型: ${status.runtimeType}', tag: 'SingBox'); - - // 确保状态更新 - kr_status.value = status; - - switch (status) { - case SingboxStopped(): - KRLogUtil.kr_i('🔴 SingBox 已停止', tag: 'SingBox'); - break; - case SingboxStarting(): - KRLogUtil.kr_i('🟡 SingBox 正在启动', tag: 'SingBox'); - break; - case SingboxStarted(): - KRLogUtil.kr_i('🟢 SingBox 已启动', tag: 'SingBox'); - kr_isFristStart.value = true; - // 使用 GetX 的方式处理 Stream 订阅 - _kr_subscribeToStats(); - _kr_subscribeToGroups(); - // 强制触发状态更新 - kr_status.refresh(); - - // 🔧 修复:启动后检查活动组是否正常更新(超时保护) - Future.delayed(const Duration(seconds: 3), () { - if (kr_activeGroups.isEmpty && kr_status.value == SingboxStarted()) { - KRLogUtil.kr_w('⚠️ SingBox已启动3秒但活动组仍为空,尝试重新订阅', tag: 'SingBox'); - _kr_subscribeToGroups(); - } - }); - break; - case SingboxStopping(): - KRLogUtil.kr_i('🟠 SingBox 正在停止', tag: 'SingBox'); - break; - } - }); - - KRLogUtil.kr_i('SingBox 初始化完成'); + KRLogUtil.kr_i('✅ SingBox 初始化完成'); _kr_isInitialized = true; } catch (e, stackTrace) { - KRLogUtil.kr_e('SingBox 初始化失败: $e'); - KRLogUtil.kr_e('错误堆栈: $stackTrace'); + KRLogUtil.kr_e('❌ SingBox 初始化失败: $e'); + KRLogUtil.kr_e('📚 错误堆栈: $stackTrace'); + + // 添加额外的诊断信息 + if (Platform.isWindows) { + try { + final workingDir = kr_configDics.workingDir; + final dataDir = Directory(p.join(workingDir.path, 'data')); + final configsDir = Directory(p.join(workingDir.path, 'configs')); + + KRLogUtil.kr_e('🔍 Windows 路径诊断信息:', tag: 'SingBox'); + KRLogUtil.kr_e(' - workingDir: ${workingDir.path}', tag: 'SingBox'); + KRLogUtil.kr_e(' - workingDir 存在: ${workingDir.existsSync()}', tag: 'SingBox'); + KRLogUtil.kr_e(' - data 目录: ${dataDir.path}', tag: 'SingBox'); + KRLogUtil.kr_e(' - data 目录存在: ${dataDir.existsSync()}', tag: 'SingBox'); + KRLogUtil.kr_e(' - configs 目录: ${configsDir.path}', tag: 'SingBox'); + KRLogUtil.kr_e(' - configs 目录存在: ${configsDir.existsSync()}', tag: 'SingBox'); + + // 检查父目录内容 + if (workingDir.existsSync()) { + try { + final contents = workingDir.listSync(); + KRLogUtil.kr_e(' - workingDir 内容: ${contents.map((e) => "${e.path.split(Platform.pathSeparator).last}${e is Directory ? "/" : ""}").join(", ")}', tag: 'SingBox'); + } catch (listErr) { + KRLogUtil.kr_e(' - 无法列出 workingDir 内容: $listErr', tag: 'SingBox'); + } + } + } catch (diagErr) { + KRLogUtil.kr_e(' - 诊断信息收集失败: $diagErr', tag: 'SingBox'); + } + } + // 如果初始化失败,允许下次重试 _kr_isInitialized = false; rethrow;