init method

  1. @override
Future<void> init()
override

初始化:释放 sing-box.exe / libcronet.dll / clash_sing_helper.exe 到应用目录, 并清除上次异常退出遗留的系统代理(崩溃自愈)。

Implementation

@override
Future<void> init() async {
  debugPrint('flutter_sing_box 插件初始化 Windows 平台 startTime = ${DateTime.now()}');
  final io.Directory dir = await ProfileStorage().getStorageDirectory();
  final singBoxResult = await AssetUtil.copyAssetToDirectory(
    WindowsConstants.singBoxAsset,
    dir.path,
  );
  if (!singBoxResult) {
    throw Exception('复制 sing_box.exe 资源失败');
  }
  final libcronetResult = await AssetUtil.copyAssetToDirectory(
    WindowsConstants.libcronetAsset,
    dir.path,
  );
  if (!libcronetResult) {
    throw Exception('复制 libcronet.dll 资源失败');
  }

  // 释放独立服务程序 clash_sing_helper.exe,供 HelperCli 调用。
  final helperResult = await AssetUtil.copyAssetToDirectory(
    WindowsConstants.helperAsset,
    dir.path,
  );
  if (!helperResult) {
    throw Exception('复制 clash_sing_helper.exe 资源失败');
  }
  // 清理上次更新遗留的 .old(三个二进制走同一重命名降级路径,都会产生)。
  // 被运行中进程锁定时删除失败是预期,忽略;服务重启路径另有 Go 侧
  // Program.Start 兜底清理(服务启动时 sing-box 必已退出,删除必成功)
  for (final String baseName in <String>[
    WindowsConstants.helperFileName,
    WindowsConstants.singBoxFileName,
    WindowsConstants.libcronetFileName,
  ]) {
    try {
      final io.File stale = _oldFileIn(dir, baseName);
      if (await stale.exists()) await stale.delete();
    } catch (_) {
      // 进程仍锁定该 .old(如服务正挂旧 helper / sing-box 未退出),留给清理
    }
  }
  // 启动期代理状态恢复:仅服务 running 时经 helper HTTP 恢复 UI 状态;
  // stopped 等其余状态跳过(stopped 时端口必无人监听,探测只会得到
  // 连接拒绝的 Unhandled Exception,而代理状态初始即 stopped 已正确)
  await restoreStartupProxyState(
    queryStatus: queryServiceStatus,
    restoreViaHttp: () => HelperHttpClient().status(),
  );
  // 崩溃自愈: 若上次异常退出遗留了系统代理,且 sing-box 当前未运行,则清除
  if (CsSettingsStorage().systemProxyActive) {
    final status = await queryServiceStatus();
    if (status != WindowsServiceStatus.running) {
      await SystemProxyService().disable();
    }
  }
  debugPrint('flutter_sing_box 插件初始化 Windows 平台 endTime = ${DateTime.now()}');
}