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

Flutter Windows端如何打开默认邮件应用并附加txt文件发送?

Flutter Windows端调用默认邮件应用并附加文件的实现方案

mailto协议本身不支持附件参数,因此你之前用url_launcher走mailto协议的方案无法实现附加文件的需求,Windows平台可以通过调用MAPI(Messaging Application Programming Interface)接口实现调用默认邮件应用携带附件的功能,具体实现如下:


1. 引入所需依赖

将以下依赖添加到项目的pubspec.yaml文件中:

dependencies:
  flutter:
    sdk: flutter
  win32: ^5.0.0 # 用于调用Windows系统API
  ffi: ^2.1.0 # 用于处理C语言类型转换
  path_provider: ^2.1.0 # 可选,用于获取应用沙盒内文件的绝对路径

2. 封装带附件发邮件的调用方法

import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:win32/win32.dart';
import 'dart:io';

/// 调用Windows默认邮件应用发信
/// [to] 收件人邮箱
/// [subject] 邮件主题
/// [body] 邮件正文
/// [attachments] 附件文件列表,必须传入绝对路径的文件
/// 返回0代表调用成功,其他值为错误码
int sendEmailWithAttachment({
  required String to,
  required String subject,
  required String body,
  required List<File> attachments,
}) {
  return using((Arena arena) {
    // 加载Windows MAPI模块
    final mapiLib = DynamicLibrary.open('mapi32.dll');
    final sendMailFunc = mapiLib.lookupFunction<
        Int32 Function(Pointer<Void> session, Pointer<Void> hwnd, Pointer<MapiMessage> message, Uint32 flags, Uint32 reserved),
        int Function(Pointer<Void> session, Pointer<Void> hwnd, Pointer<MapiMessage> message, int flags, int reserved)
      >('MAPISendMailW');

    // 构造收件人信息
    final recipient = arena<MapiRecipDesc>();
    recipient.ref.ulRecipClass = MAPI_TO;
    recipient.ref.lpszName = to.toNativeUtf16(allocator: arena).cast();
    recipient.ref.lpszAddress = 'SMTP:${to}'.toNativeUtf16(allocator: arena).cast();

    // 构造附件列表
    final mapiAttachments = arena<MapiFileDesc>(attachments.length);
    for (var i = 0; i < attachments.length; i++) {
      final filePath = attachments[i].absolute.path.toNativeUtf16(allocator: arena);
      mapiAttachments[i].ulReserved = 0;
      mapiAttachments[i].flFlags = 0;
      mapiAttachments[i].nPosition = 0xFFFFFFFF;
      mapiAttachments[i].lpszPathName = filePath.cast();
      mapiAttachments[i].lpszFileName = filePath.cast();
      mapiAttachments[i].lpFileType = nullptr;
    }

    // 构造邮件主体
    final message = arena<MapiMessage>();
    message.ref.ulReserved = 0;
    message.ref.lpszSubject = subject.toNativeUtf16(allocator: arena).cast();
    message.ref.lpszNoteText = body.toNativeUtf16(allocator: arena).cast();
    message.ref.nRecipCount = 1;
    message.ref.lpRecips = recipient;
    message.ref.nFileCount = attachments.length;
    message.ref.lpFiles = mapiAttachments;

    // 触发系统邮件应用弹窗
    return sendMailFunc(nullptr, nullptr, message, MAPI_LOGON_UI | MAPI_DIALOG, 0);
  });
}

3. 调用示例

// 调用前先判断当前平台为Windows
if (Platform.isWindows) {
  final testTxt = File('C:/用户/公共/测试文件.txt'); // 必须传入绝对路径的文件
  sendEmailWithAttachment(
    to: 'test@example.com',
    subject: '测试带附件邮件',
    body: '这是邮件正文内容',
    attachments: [testTxt],
  );
}

注意事项

  • 该方案仅适用于Windows平台,调用前必须做平台判断,避免其他平台运行报错
  • 若用户设备未安装任何邮件客户端,调用后会弹出系统引导提示,让用户选择/安装默认邮件应用
  • 附件必须传入绝对路径,若需要发送应用沙盒内的文件,可先通过path_provider获取文件的绝对路径后再传入

内容的提问来源于stack exchange,提问作者Andrew Klement Winarto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 23:36:09