Files
desktop-plugin/lib/main.dart
T
dzc 98df601f7b fix: main 启动链路全防御——runApp 前异常不再导致白屏窗口
用户实测:安装包在开发机一切正常,其他电脑白屏(产物完整、开发机可跑)。
结构性隐患:runApp 之前的 windowManager/单实例/scheme 注册/托盘任一步在
目标机环境差异下抛异常,Dart 永远不会 runApp(窗口由原生已创建)= 白屏,
开发机顺利复现不了。全部步骤 try-catch:非关键步骤(scheme/托盘)失败仅记
日志不阻断;关键失败聚合为 bootWarning 在界面错误视图中显示。
2026-09-21 19:05:06 +08:00

115 lines
3.9 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:window_manager/window_manager.dart';
import 'agent.dart';
import 'setup/single_instance.dart';
import 'setup/url_scheme.dart';
import 'ui/app_shell.dart';
import 'ui/app_tray.dart';
/// 资安信插件助手(desktop-plugin):桌面插件集成软件。
/// 当前内置插件:饭卡打印机(card-printer);左侧菜单与插件页均由 lib/ui/routes.dart 驱动。
/// 关闭窗口 = 最小化到后台托盘,服务持续运行;退出入口在托盘菜单。
///
/// 健壮性铁律:runApp 之前的任何非关键步骤(托盘/scheme 注册/单实例)一律
/// try-catch 吞错并记日志——否则在目标机环境差异下抛异常会让界面永远起不来
/// (窗口由原生创建、Dart 未 runApp = 白屏窗口),开发机上无法复现。
Future<void> main(List<String> args) async {
WidgetsFlutterBinding.ensureInitialized();
String? bootWarning;
try {
await windowManager.ensureInitialized();
} catch (e) {
bootWarning = '窗口管理初始化失败:$e';
}
// 单实例:zaxprint:// 唤起或重复双击会启动第二进程——通知常驻实例弹窗后自己退出
bool isPrimary = true;
try {
isPrimary = await SingleInstance.acquire(
onWake: () async {
await windowManager.show();
await windowManager.focus();
},
);
} catch (e) {
bootWarning = '${bootWarning == null ? "" : "$bootWarning\n"}单实例检测失败:$e';
}
if (!isPrimary) {
exit(0);
}
final agent = Agent(AgentOptions.parse(args));
String? startError;
try {
await agent.start();
} catch (e) {
startError = '$e';
}
try {
await UrlScheme.ensureRegistered(); // Windows 运行时注册 zaxprint://;mac 由 Info.plist 声明
} catch (e) {
agent.log.write('网页唤起协议注册失败(不影响其他功能):$e');
}
final appTray = AppTray(agent: agent);
try {
await appTray.start();
} catch (e) {
agent.log.write('托盘初始化失败(不影响其他功能):$e');
}
runApp(DesktopPluginApp(agent: agent, startError: startError ?? bootWarning));
}
class DesktopPluginApp extends StatelessWidget {
const DesktopPluginApp({super.key, required this.agent, this.startError});
final Agent agent;
final String? startError;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '资安信插件助手',
debugShowCheckedModeBanner: false,
theme: _darkTheme(),
home: AppShell(agent: agent, startError: startError),
);
}
/// 深色运维风格(ui-ux-pro-max 设计系统:OLED 深底 + 运维三色语义)。
ThemeData _darkTheme() {
final base = ThemeData(brightness: Brightness.dark, useMaterial3: true);
final scheme = base.colorScheme.copyWith(
// 正常/主操作:operational green
primary: const Color(0xFF4ADE80),
onPrimary: const Color(0xFF052E16),
primaryContainer: const Color(0xFF14532D),
onPrimaryContainer: const Color(0xFFDCFCE7),
// 故障红
error: const Color(0xFFF87171),
errorContainer: const Color(0xFF7F1D1D),
onErrorContainer: const Color(0xFFFEE2E2),
// 表面层级:#0F172A 底 / #111827 卡 / #1E293B 强调
surface: const Color(0xFF0F172A),
onSurface: const Color(0xFFF8FAFC),
onSurfaceVariant: const Color(0xFFCBD5E1),
surfaceContainerLow: const Color(0xFF111827),
surfaceContainerHighest: const Color(0xFF1E293B),
outlineVariant: const Color(0xFF334155),
);
return base.copyWith(
colorScheme: scheme,
scaffoldBackgroundColor: const Color(0xFF0F172A),
cardTheme: const CardTheme(color: Color(0xFF111827)),
snackBarTheme: const SnackBarThemeData(behavior: SnackBarBehavior.floating),
dividerTheme: const DividerThemeData(color: Color(0xFF334155), thickness: 1),
);
}
}