升级Dart 2.12.1后Windows下Process.runSync调用pub get报找不到文件错误
问题根因与修复方案
核心问题定位
这个报错是Dart 2.11+版本在Windows平台的行为变更导致,和你之前排查的PATH配置、权限设置、运行shell没有任何关系:
- Dart 2.9.x及更早版本的Windows SDK目录下,存在独立的原生可执行文件
pub.exe,Process.runSync可以直接通过文件名匹配到对应程序 - 从Dart 2.12开始,官方彻底移除了独立的pub原生可执行文件,将pub的所有逻辑整合为
dart.exe的内置子命令,SDK目录下仅保留一个pub.bat批处理引导脚本 - Dart的
Process.runSync在Windows平台查找可执行文件时,默认只会匹配原生PE可执行程序,不会自动遍历追加.bat/.cmd后缀去匹配批处理文件;而PowerShell、CMD这类系统shell本身内置批处理解析逻辑,所以你手动敲pub get完全正常,但Dart进程直接调用就会触发“找不到文件”的报错 - 就算你将SDK bin目录完整配置到系统PATH,因为Process不会自动补全.bat后缀,依然会匹配不到目标文件,这也是你之前所有PATH校验都通过、但运行依然报错的核心原因。
可落地修复方案
- 优先使用官方推荐的无版本冲突写法
直接绕过独立pub的调用,改成调用当前运行的dart程序的内置pub子命令,替换原有代码即可:
这种写法完全不依赖PATH环境变量配置,自动匹配当前测试运行时使用的Dart SDK版本,不会出现本地手动运行、CI环境运行的版本不一致问题。// 原报错代码 Process.runSync('pub', ['get'], workingDirectory: stubPath); // 修复后代码 Process.runSync('dart', ['pub', 'get'], workingDirectory: stubPath); - 如果需要兼容跨平台老调用逻辑
在调用前通过平台判断显式指定文件后缀:final pubExecutable = Platform.isWindows ? 'pub.bat' : 'pub'; Process.runSync(pubExecutable, ['get'], workingDirectory: stubPath); - 更稳妥的绝对路径写法
完全不依赖PATH的查找逻辑,直接基于当前运行的dart可执行文件推导pub的路径,从根源避免查找失败:final dartExecutable = Platform.resolvedExecutable; final sdkBinDir = File(dartExecutable).parent; final pubExecutable = Platform.isWindows ? sdkBinDir.uri.resolve('pub.bat').toFilePath() : sdkBinDir.uri.resolve('pub').toFilePath(); Process.runSync(pubExecutable, ['get'], workingDirectory: stubPath);
常见排查误区说明
- 你之前尝试的PowerShell/CMD/管理员权限运行均复现问题,本质是因为Process本身的文件查找逻辑不支持批处理后缀,和权限、shell类型无关
- 手动在shell中运行
pub get正常,是因为shell本身会自动解析PATH下的.bat批处理文件,这个能力和Dart Process的文件查找逻辑是相互独立的
内容的提问来源于stack exchange,提问作者Driky
相关产品推荐
相关产品推荐

