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

.NET Framework调用默认邮件应用创建带正文及附件的邮件方法

.NET Framework 唤起默认邮件客户端新建带附件邮件的实现方案

最优实现:调用Windows原生MAPI接口

该方案不依赖特定邮件客户端,兼容所有支持MAPI规范的主流邮件客户端(包括Outlook、Foxmail、Thunderbird等),支持批量添加附件,无需引入第三方依赖。

第一步:封装MAPI调用帮助类

首先通过P/Invoke声明Windows MAPI接口的相关结构和方法,完整代码如下:

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

public static class MailHelper
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    private class MapiFileDesc
    {
        public int reserved = 0;
        public int flags = 0;
        public int position = 0;
        public string path = null;
        public string name = null;
        public IntPtr type = IntPtr.Zero;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    private class MapiMessage
    {
        public int reserved = 0;
        public string subject = null;
        public string body = null;
        public int receiptRequested = 0;
        public IntPtr interop = IntPtr.Zero;
        public string originator = null;
        public int recipientCount = 0;
        public IntPtr recipients = IntPtr.Zero;
        public int fileCount = 0;
        public IntPtr files = IntPtr.Zero;
    }

    [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
    private static extern int MAPISendMail(IntPtr session, IntPtr hwnd, MapiMessage message, int flags, int reserved);

    private const int MAPI_LOGON_UI = 0x00000001;
    private const int MAPI_DIALOG = 0x00000008;
    private const int SUCCESS_SUCCESS = 0;

    /// <summary>
    /// 唤起默认邮件客户端新建带附件的邮件
    /// </summary>
    /// <param name="subject">邮件主题</param>
    /// <param name="body">邮件正文</param>
    /// <param name="attachmentPaths">附件文件的本地完整路径列表</param>
    /// <returns>调用是否成功</returns>
    public static bool SendMail(string subject, string body, List<string> attachmentPaths)
    {
        var message = new MapiMessage
        {
            subject = subject,
            body = body
        };

        // 处理附件
        if (attachmentPaths != null && attachmentPaths.Count > 0)
        {
            message.fileCount = attachmentPaths.Count;
            var fileDescPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(MapiFileDesc)) * attachmentPaths.Count);
            var currentPtr = fileDescPtr;
            foreach (var path in attachmentPaths)
            {
                var fileDesc = new MapiFileDesc
                {
                    path = path
                };
                Marshal.StructureToPtr(fileDesc, currentPtr, false);
                currentPtr += Marshal.SizeOf(typeof(MapiFileDesc));
            }
            message.files = fileDescPtr;
        }

        try
        {
            int result = MAPISendMail(IntPtr.Zero, IntPtr.Zero, message, MAPI_LOGON_UI | MAPI_DIALOG, 0);
            return result == SUCCESS_SUCCESS;
        }
        finally
        {
            // 释放非托管内存
            if (message.files != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(message.files);
            }
        }
    }
}

第二步:按钮点击事件中调用

private void btnSendMail_Click(object sender, EventArgs e)
{
    // 示例参数
    var attachments = new List<string>
    {
        @"C:\Users\Public\Documents\test1.pdf",
        @"C:\Users\Public\Documents\test2.xlsx"
    };
    MailHelper.SendMail("测试邮件主题", "这是邮件正文内容", attachments);
}

注意事项

  • 调用前需校验附件文件存在,且当前程序拥有附件的读取权限,否则会调用失败
  • 仅极少数小众邮件客户端不支持MAPI协议,这类场景占比极低,常规业务无需额外兼容
  • 该实现兼容.NET Framework 4.0及以上所有版本,无需引入额外NuGet包或依赖

内容的提问来源于stack exchange,提问作者George

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 15:45:02