You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Windows应用如何捕获窗口关闭事件并执行自定义操作?

Flutter Windows捕获窗口关闭事件实现方案

方法一:使用window_manager快速实现

这是最简便的方案,借助成熟的第三方包处理窗口生命周期事件:

  1. 添加依赖到pubspec.yaml:
dependencies:
  window_manager: ^0.3.8
  1. 初始化窗口管理器:
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await windowManager.ensureInitialized();
  runApp(const MyApp());
}
  1. 在主页面监听窗口关闭事件:
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端代码

  1. 创建平台通道:
class WindowCloseChannel {
  static const _channel = MethodChannel('window_close_channel');

  static Future<bool> requestCloseConfirmation() async {
    return await _channel.invokeMethod('requestClose') ?? false;
  }
}
  1. 绑定生命周期监听并处理关闭逻辑:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 15:40:21