用户实测:安装包在开发机一切正常,其他电脑白屏(产物完整、开发机可跑)。 结构性隐患:runApp 之前的 windowManager/单实例/scheme 注册/托盘任一步在 目标机环境差异下抛异常,Dart 永远不会 runApp(窗口由原生已创建)= 白屏, 开发机顺利复现不了。全部步骤 try-catch:非关键步骤(scheme/托盘)失败仅记 日志不阻断;关键失败聚合为 bootWarning 在界面错误视图中显示。
115 lines
3.9 KiB
Dart
115 lines
3.9 KiB
Dart
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),
|
||
);
|
||
}
|
||
}
|