import 'dart:io'; import 'package:path/path.dart' as p; /// 路径工具类 - 获取应用根目录和 bin 目录 class PathUtils { static String? _cachedAppRoot; /// 获取应用根目录 /// 在发布模式下,返回 .exe 文件所在目录 /// 在开发模式下,返回 windows 目录(因为 bin 文件夹在 windows/bin 下) static String get appRoot { if (_cachedAppRoot != null) { return _cachedAppRoot!; } try { // 尝试获取可执行文件所在目录 final exePath = Platform.resolvedExecutable; final exeDir = p.dirname(exePath); // 检查是否是开发模式(可执行文件在 build 目录下) if (exeDir.contains('build') || exeDir.contains('windows\\build') || exeDir.contains('windows/build')) { // 开发模式:bin 文件夹在 windows/bin 下 // 从可执行文件路径向上查找 windows 目录 var currentPath = exeDir; var foundWindows = false; // 向上查找,直到找到包含 'windows' 且不是 'build\windows' 的目录 while (currentPath.isNotEmpty) { final dirName = p.basename(currentPath); final parent = p.dirname(currentPath); // 如果当前目录名是 'windows',且不在 build 路径中,说明找到了项目根目录下的 windows 目录 if (dirName == 'windows' && !currentPath.contains('build\\windows') && !currentPath.contains('build/windows')) { // 检查这个 windows 目录下是否有 bin 文件夹 final binPath = p.join(currentPath, 'bin'); if (Directory(binPath).existsSync()) { _cachedAppRoot = currentPath; foundWindows = true; break; } } if (parent == currentPath) break; // 到达根目录 currentPath = parent; } if (foundWindows) { return _cachedAppRoot!; } // 如果向上查找失败,尝试从当前工作目录查找 final currentDir = Directory.current.path; if (currentDir.contains('windows')) { // 找到 windows 目录 final parts = currentDir.split(RegExp(r'[\\/]')); var windowsIndex = -1; for (int i = 0; i < parts.length; i++) { if (parts[i] == 'windows') { windowsIndex = i; break; } } if (windowsIndex >= 0) { final windowsDir = parts.sublist(0, windowsIndex + 1).join(Platform.pathSeparator); final binPath = p.join(windowsDir, 'bin'); if (Directory(binPath).existsSync()) { _cachedAppRoot = windowsDir; return _cachedAppRoot!; } } } } // 发布模式:可执行文件和 bin 文件夹在同一目录 _cachedAppRoot = exeDir; return _cachedAppRoot!; } catch (e) { // 如果获取失败,尝试使用当前工作目录 final currentDir = Directory.current.path; if (currentDir.contains('windows')) { // 找到 windows 目录 final parts = currentDir.split(RegExp(r'[\\/]')); var windowsIndex = -1; for (int i = 0; i < parts.length; i++) { if (parts[i] == 'windows') { windowsIndex = i; break; } } if (windowsIndex >= 0) { final windowsDir = parts.sublist(0, windowsIndex + 1).join(Platform.pathSeparator); final binPath = p.join(windowsDir, 'bin'); if (Directory(binPath).existsSync()) { _cachedAppRoot = windowsDir; return _cachedAppRoot!; } } } _cachedAppRoot = currentDir; return _cachedAppRoot!; } } /// 获取 bin 目录路径 static String get binDir { final root = appRoot; return p.join(root, 'bin'); } /// 获取 bin 目录下的文件路径 static String binFile(String filename) { return p.join(binDir, filename); } }