windows路径问题

(cherry picked from commit 9cefb1b9e009575ee7f6a5aef631cb344b6e1df8)
This commit is contained in:
Rust 2025-10-29 16:07:16 +08:00 committed by speakeloudest
parent 0067017ca6
commit 9c2f9be6c5
3 changed files with 210 additions and 7 deletions

View File

@ -177,36 +177,225 @@ class KRSingBoxImp {
final workingDir = final workingDir =
Platform.isAndroid ? await getExternalStorageDirectory() : baseDir; Platform.isAndroid ? await getExternalStorageDirectory() : baseDir;
final tempDir = await getTemporaryDirectory(); final tempDir = await getTemporaryDirectory();
// Windows 使
Directory normalizePath(Directory dir) {
if (Platform.isWindows) {
final normalized = dir.path.replaceAll('/', '\\');
if (normalized != dir.path) {
KRLogUtil.kr_i('路径规范化: ${dir.path} -> $normalized', tag: 'SingBox');
return Directory(normalized);
}
}
return dir;
}
kr_configDics = ( kr_configDics = (
baseDir: baseDir, baseDir: normalizePath(baseDir),
workingDir: workingDir!, workingDir: normalizePath(workingDir!),
tempDir: tempDir, tempDir: normalizePath(tempDir),
); );
KRLogUtil.kr_i('其他平台路径初始化完成'); KRLogUtil.kr_i('其他平台路径初始化完成');
} }
KRLogUtil.kr_i('开始创建目录'); KRLogUtil.kr_i('开始创建目录');
KRLogUtil.kr_i('baseDir: ${kr_configDics.baseDir.path}', tag: 'SingBox');
KRLogUtil.kr_i('workingDir: ${kr_configDics.workingDir.path}', tag: 'SingBox');
KRLogUtil.kr_i('tempDir: ${kr_configDics.tempDir.path}', tag: 'SingBox');
//
if (!kr_configDics.baseDir.existsSync()) { if (!kr_configDics.baseDir.existsSync()) {
await kr_configDics.baseDir.create(recursive: true); await kr_configDics.baseDir.create(recursive: true);
KRLogUtil.kr_i('已创建 baseDir', tag: 'SingBox');
} }
if (!kr_configDics.workingDir.existsSync()) { if (!kr_configDics.workingDir.existsSync()) {
await kr_configDics.workingDir.create(recursive: true); await kr_configDics.workingDir.create(recursive: true);
KRLogUtil.kr_i('已创建 workingDir', tag: 'SingBox');
} }
if (!kr_configDics.tempDir.existsSync()) { if (!kr_configDics.tempDir.existsSync()) {
await kr_configDics.tempDir.create(recursive: true); await kr_configDics.tempDir.create(recursive: true);
KRLogUtil.kr_i('已创建 tempDir', tag: 'SingBox');
} }
// libcore data workingDir
// libcore Setup os.Chdir(workingPath) data workingDir
final dataDir = Directory(p.join(kr_configDics.workingDir.path, 'data'));
// data Windows
int retryCount = 0;
const maxRetries = 5;
while (!dataDir.existsSync() && retryCount < maxRetries) {
try {
await dataDir.create(recursive: true);
// Windows
await Future.delayed(const Duration(milliseconds: 100));
//
if (dataDir.existsSync()) {
KRLogUtil.kr_i('✅ 已创建 data 目录: ${dataDir.path}', tag: 'SingBox');
break;
} else {
retryCount++;
KRLogUtil.kr_i('⚠️ data 目录创建后验证失败,重试 $retryCount/$maxRetries', tag: 'SingBox');
await Future.delayed(const Duration(milliseconds: 200));
}
} catch (e) {
retryCount++;
KRLogUtil.kr_e('❌ 创建 data 目录失败 (尝试 $retryCount/$maxRetries): $e', tag: 'SingBox');
if (retryCount >= maxRetries) {
throw Exception('无法创建 libcore 数据库目录: ${dataDir.path},错误: $e');
}
final delayMs = 200 * retryCount;
await Future.delayed(Duration(milliseconds: delayMs));
}
}
if (!dataDir.existsSync()) {
final error = 'data 目录不存在: ${dataDir.path}';
KRLogUtil.kr_e('$error', tag: 'SingBox');
throw Exception(error);
}
//
try {
final testFile = File(p.join(dataDir.path, '.test_write'));
await testFile.writeAsString('test');
await testFile.delete();
KRLogUtil.kr_i('✅ data 目录写入权限验证通过', tag: 'SingBox');
} catch (e) {
KRLogUtil.kr_e('⚠️ data 目录写入权限验证失败: $e', tag: 'SingBox');
// libcore
}
// Windows
if (Platform.isWindows) {
await Future.delayed(const Duration(milliseconds: 300));
KRLogUtil.kr_i('⏳ Windows 文件系统同步等待完成', tag: 'SingBox');
}
// setup() workingDir data 访
// libcore Setup() os.Chdir(workingPath)使 "./data"
// os.Chdir() 访
if (!kr_configDics.workingDir.existsSync()) {
final error = '❌ workingDir 不存在,无法调用 setup(): ${kr_configDics.workingDir.path}';
KRLogUtil.kr_e(error, tag: 'SingBox');
throw Exception(error);
}
// workingDir
try {
final testWorkingFile = File(p.join(kr_configDics.workingDir.path, '.test_working_dir'));
await testWorkingFile.writeAsString('test');
await testWorkingFile.delete();
KRLogUtil.kr_i('✅ workingDir 写入权限验证通过', tag: 'SingBox');
} catch (e) {
final error = '❌ workingDir 无写入权限: ${kr_configDics.workingDir.path}, 错误: $e';
KRLogUtil.kr_e(error, tag: 'SingBox');
throw Exception(error);
}
final finalDataDir = Directory(p.join(kr_configDics.workingDir.path, 'data'));
if (!finalDataDir.existsSync()) {
KRLogUtil.kr_e('❌ 最终验证失败data 目录不存在', tag: 'SingBox');
KRLogUtil.kr_e('路径: ${finalDataDir.path}', tag: 'SingBox');
KRLogUtil.kr_e('workingDir 是否存在: ${kr_configDics.workingDir.existsSync()}', tag: 'SingBox');
if (kr_configDics.workingDir.existsSync()) {
try {
final workingDirContents = kr_configDics.workingDir.listSync();
KRLogUtil.kr_e('workingDir 内容: ${workingDirContents.map((e) => e.path.split(Platform.pathSeparator).last).join(", ")}', tag: 'SingBox');
} catch (e) {
KRLogUtil.kr_e('无法列出 workingDir 内容: $e', tag: 'SingBox');
}
}
throw Exception('data 目录在 setup() 前验证失败: ${finalDataDir.path}');
}
//
try {
final verifyFile = File(p.join(finalDataDir.path, '.verify_setup'));
await verifyFile.writeAsString('verify');
await verifyFile.delete();
KRLogUtil.kr_i('✅ setup() 前最终验证通过', tag: 'SingBox');
} catch (e) {
KRLogUtil.kr_e('❌ setup() 前最终验证失败: $e', tag: 'SingBox');
// setup()
}
if (!directory.existsSync()) { if (!directory.existsSync()) {
await directory.create(recursive: true); await directory.create(recursive: true);
KRLogUtil.kr_i('已创建 configs 目录', tag: 'SingBox');
} }
KRLogUtil.kr_i('目录创建完成'); KRLogUtil.kr_i('目录创建完成', tag: 'SingBox');
KRLogUtil.kr_i('开始设置 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');
KRLogUtil.kr_i(' - tempDir: ${kr_configDics.tempDir.path}', tag: 'SingBox');
KRLogUtil.kr_i(' - data 目录: ${p.join(kr_configDics.workingDir.path, "data")}', tag: 'SingBox');
KRLogUtil.kr_i(' - data 目录存在: ${finalDataDir.existsSync()}', tag: 'SingBox');
// Windows data
if (Platform.isWindows && finalDataDir.existsSync()) {
try {
final dataContents = finalDataDir.listSync();
if (dataContents.isNotEmpty) {
KRLogUtil.kr_i(' - data 目录现有文件: ${dataContents.map((e) => e.path.split(Platform.pathSeparator).last).join(", ")}', tag: 'SingBox');
} else {
KRLogUtil.kr_i(' - data 目录为空', tag: 'SingBox');
}
} catch (e) {
KRLogUtil.kr_e(' - 无法列出 data 目录内容: $e', tag: 'SingBox');
}
}
KRLogUtil.kr_i(' - libcore 将通过 os.Chdir() 切换到: ${kr_configDics.workingDir.path}', tag: 'SingBox');
KRLogUtil.kr_i(' - 然后使用相对路径 "./data" 访问数据库', tag: 'SingBox');
// Windows
if (Platform.isWindows) {
final workingPath = kr_configDics.workingDir.path;
if (workingPath.contains('/')) {
KRLogUtil.kr_e('⚠️ 警告Windows 路径包含正斜杠,可能导致问题: $workingPath', tag: 'SingBox');
}
// 使Windows
final normalizedPath = workingPath.replaceAll('/', '\\');
if (normalizedPath != workingPath) {
KRLogUtil.kr_e('⚠️ 路径格式可能需要规范化: $workingPath -> $normalizedPath', tag: 'SingBox');
}
}
await kr_singBox.setup(kr_configDics, false).map((r) { await kr_singBox.setup(kr_configDics, false).map((r) {
KRLogUtil.kr_i('SingBox 设置成功'); KRLogUtil.kr_i('✅ SingBox setup() 调用成功', tag: 'SingBox');
// setup()
// Windows libcore
if (Platform.isWindows) {
KRLogUtil.kr_i('⏳ Windows: 等待 libcore 服务初始化完成...', tag: 'SingBox');
}
return r;
}).mapLeft((err) { }).mapLeft((err) {
KRLogUtil.kr_e('SingBox 设置失败: $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; throw err;
}).run(); }).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 选项');
KRLogUtil.kr_i('📋 SingBox 配置选项: ${oOption.toJson()}', tag: 'SingBox'); KRLogUtil.kr_i('📋 SingBox 配置选项: ${oOption.toJson()}', tag: 'SingBox');

View File

@ -27,6 +27,13 @@ class KRSecureStorage {
if (Platform.isMacOS || Platform.isWindows || Platform.isLinux) { if (Platform.isMacOS || Platform.isWindows || Platform.isLinux) {
final baseDir = await getApplicationSupportDirectory(); final baseDir = await getApplicationSupportDirectory();
KRLogUtil.kr_i('初始化 Hive路径: ${baseDir.path}', tag: 'SecureStorage'); KRLogUtil.kr_i('初始化 Hive路径: ${baseDir.path}', tag: 'SecureStorage');
//
if (!baseDir.existsSync()) {
await baseDir.create(recursive: true);
KRLogUtil.kr_i('已创建 Hive 目录: ${baseDir.path}', tag: 'SecureStorage');
}
await Hive.initFlutter(baseDir.path); await Hive.initFlutter(baseDir.path);
} else { } else {
// Android iOS 使 // Android iOS 使
@ -39,6 +46,7 @@ class KRSecureStorage {
KRLogUtil.kr_i('Hive 初始化成功', tag: 'SecureStorage'); KRLogUtil.kr_i('Hive 初始化成功', tag: 'SecureStorage');
} catch (e, stackTrace) { } catch (e, stackTrace) {
KRLogUtil.kr_e('初始化 Hive 失败: $e', tag: 'SecureStorage'); KRLogUtil.kr_e('初始化 Hive 失败: $e', tag: 'SecureStorage');
KRLogUtil.kr_e('错误类型: ${e.runtimeType}', tag: 'SecureStorage');
KRLogUtil.kr_e('错误堆栈: $stackTrace', tag: 'SecureStorage'); KRLogUtil.kr_e('错误堆栈: $stackTrace', tag: 'SecureStorage');
// Windows Linux // Windows Linux

View File

@ -2,6 +2,12 @@
cmake_minimum_required(VERSION 3.14) cmake_minimum_required(VERSION 3.14)
project(BearVPN LANGUAGES CXX) project(BearVPN LANGUAGES CXX)
# CMake
# CMP0175: add_custom_command() flutter_inappwebview_windows
if(POLICY CMP0175)
cmake_policy(SET CMP0175 OLD)
endif()
# #
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")