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

C#使用MimeMessage.WriteTo生成Outlook .msg文件无法打开问题求助

问题根源

你误用了MimeMessage.WriteTo方法的输出格式:MimeKit提供的WriteTo方法生成的是标准EML(符合RFC822规范)格式的邮件内容,并非微软专属的Outlook MSG二进制复合文件格式。你只是把生成的EML文件后缀修改为了.msg,本质还是EML文件,Outlook识别到格式不匹配就会抛出异常,这和权限、文件占用没有任何关系,也是两种方案生成的文件大小差距巨大的根本原因。

免费实现方案

如果不想采购IndependentSoft的商业授权,可以根据你的部署场景选择以下两种免费方案:

  • 方案1:依赖Outlook环境的Interop方案(适合客户端场景,不推荐服务端使用)
    前提是运行环境已安装Outlook,示例代码如下:
    using System.IO;
    using System.Runtime.InteropServices;
    using MimeKit;
    using Microsoft.Office.Interop.Outlook;
    
    public static byte[] ConvertMimeToMSG(MimeMessage mm)
    {
        if (mm == null) return null;
        
        // 生成临时EML文件
        string tempEmlPath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.eml");
        mm.WriteTo(tempEmlPath);
        
        // 用Outlook打开EML另存为MSG
        Application outlookApp = new Application();
        MailItem mailItem = (MailItem)outlookApp.Session.OpenSharedItem(tempEmlPath);
        
        string tempMsgPath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.msg");
        mailItem.SaveAs(tempMsgPath, OlSaveAsType.olMSG);
        
        // 读取MSG字节流
        byte[] msgBytes = File.ReadAllBytes(tempMsgPath);
        
        // 清理临时文件和COM对象
        File.Delete(tempEmlPath);
        File.Delete(tempMsgPath);
        Marshal.ReleaseComObject(mailItem);
        Marshal.ReleaseComObject(outlookApp);
        
        return msgBytes;
    }
    
  • 方案2:使用开源MsgKit库实现纯代码转换(服务端、客户端均适用,MIT协议可免费商用)
    首先通过NuGet安装MsgKit包,示例代码如下:
    using System.IO;
    using System.Linq;
    using MimeKit;
    using MsgKit;
    using MsgKit.Enums;
    
    public static byte[] ConvertMimeToMSG(MimeMessage mm)
    {
        if (mm == null) return null;
        
        using var ms = new MemoryStream();
        // 提取发件人信息
        var from = mm.From.OfType<MailboxAddress>().FirstOrDefault();
        if (from == null) return null;
        
        // 构造MSG对象
        using var msg = new Message(
            new Sender(from.Address, from.Name),
            mm.To.Select(t => new Recipient(RecipientType.To, ((MailboxAddress)t).Address, ((MailboxAddress)t).Name)).ToList(),
            mm.Subject);
        
        // 填充正文
        msg.BodyText = mm.TextBody;
        msg.BodyHtml = mm.HtmlBody;
        msg.Date = mm.Date.DateTime;
        
        // 填充附件
        foreach (var attachment in mm.Attachments.OfType<MimePart>())
        {
            using var attachStream = new MemoryStream();
            attachment.Content.DecodeTo(attachStream);
            msg.Attachments.Add(attachment.FileName, attachStream.ToArray());
        }
        
        // 可按需补充抄送、密送、优先级等其他属性
        
        msg.Save(ms);
        return ms.ToArray();
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 16:48:04