Flutter Windows应用如何捕获窗口关闭事件并执行自定义操作?
Flutter Windows捕获窗口关闭事件实现方案
方法一:使用window_manager快速实现
这是最简便的方案,借助成熟的第三方包处理窗口生命周期事件:
- 添加依赖到
pubspec.yaml:
dependencies: window_manager: ^0.3.8
- 初始化窗口管理器:
void main() async { WidgetsFlutterBinding.ensureInitialized(); await windowManager.ensureInitialized(); runApp(const MyApp()); }
- 在主页面监听窗口关闭事件:
class _MyHomePageState extends State<MyHomePage> with WindowListener { @override void initState() { super.initState(); windowManager.addListener(this); } @override void dispose() { windowManager.removeListener(this); super.dispose(); } @override void onWindowClose() async { // 弹出确认对话框 final shouldClose = await showDialog<bool>( context: context, barrierDismissible: false, builder: (_) => AlertDialog( title: const Text('确认退出'), content: const Text('确定要关闭应用吗?'), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(false), child: const Text('取消'), ), TextButton( onPressed: () => Navigator.of(context).pop(true), child: const Text('确定'), ), ], ), ) ?? false; if (shouldClose) { // 终止目标进程,替换为你的进程名 await Process.run('taskkill', ['/F', '/IM', 'target_process.exe']); // 允许窗口关闭 windowManager.destroy(); } else { // 阻止窗口关闭 windowManager.preventClose(); } } @override Widget build(BuildContext context) { return Scaffold( // 你的页面内容 ); } }
方法二:原生平台通道实现(无第三方依赖)
如果不想依赖第三方包,可以通过Flutter平台通道直接对接Windows原生API:
Flutter端代码
- 创建平台通道:
class WindowCloseChannel { static const _channel = MethodChannel('window_close_channel'); static Future<bool> requestCloseConfirmation() async { return await _channel.invokeMethod('requestClose') ?? false; } }
- 绑定生命周期监听并处理关闭逻辑:
class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver { @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); } @override void dispose() { WidgetsBinding.instance.removeObserver(this); super.dispose(); } Future<bool> _handleCloseRequest() async { final shouldClose = await showDialog<bool>( context: context, barrierDismissible: false, builder: (_) => AlertDialog( title: const Text('确认退出'), content: const Text('确定要关闭应用吗?'), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(false), child: const Text('取消'), ), TextButton( onPressed: () => Navigator.of(context).pop(true), child: const Text('确定'), ), ], ), ) ?? false; if (shouldClose) { // 终止目标进程 await Process.run('taskkill', ['/F', '/IM', 'target_process.exe']); } return shouldClose; } }
Windows原生代码修改
打开windows/runner/main.cpp,修改窗口消息处理逻辑:
#include <flutter/dart_project.h> #include <flutter/flutter_view_controller.h> #include <windows.h> #include "flutter_window.h" #include "utils.h" int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, _In_ wchar_t *command_line, _In_ int show_command) { dart_project project(L"data"); FlutterWindow window(project); Win32Window::Point origin(10, 10); Win32Window::Size size(1280, 720); if (!window.CreateAndShow(L"你的应用名称", origin, size)) { return EXIT_FAILURE; } window.SetQuitOnClose(false); // 禁用默认关闭行为 MSG msg; while (GetMessage(&msg, nullptr, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); if (msg.message == WM_CLOSE) { // 调用Flutter端的确认逻辑 auto result = window.flutter_controller()->engine()->channel_method_call_handler() ->InvokeMethod("requestClose", nullptr); bool should_close = std::get<bool>(*result); if (should_close) { DestroyWindow(msg.hwnd); } continue; } } return EXIT_SUCCESS; }
关于终止进程的说明
使用dart:io的Process.run调用Windows的taskkill命令即可终止进程:
/F:强制终止进程/IM:指定进程名(如notepad.exe)
如果目标进程需要管理员权限,可能需要额外处理权限提升逻辑。
内容的提问来源于stack exchange,提问作者gregory jithin
相关产品推荐
相关产品推荐

