在C#中解析.eml文件的建议

48

我有一个包含电子邮件对话的.eml文件目录。在C#中,解析这种类型的文件有推荐的方法吗?

8个回答

68

2017年8月更新:看看MimeKit:https://github.com/jstedfast/MimeKit。它支持.NET Standard,因此可以跨平台运行。

原回答:我在Github上发布了一个示例项目来说明这个答案 to Github

CDO COM DLL是Windows/IIS的一部分,可以在.net中引用。它将提供准确的解析和良好的对象模型。与ADODB.DLL的引用一起使用。

public CDO.Message LoadEmlFromFile(String emlFileName)
{
    CDO.Message msg = new CDO.MessageClass();
    ADODB.Stream stream = new ADODB.StreamClass();

    stream.Open(Type.Missing, ADODB.ConnectModeEnum.adModeUnknown, ADODB.StreamOpenOptionsEnum.adOpenStreamUnspecified, String.Empty, String.Empty);
    stream.LoadFromFile(emlFileName);
    stream.Flush();
    msg.DataSource.OpenObject(stream, "_Stream");
    msg.DataSource.Save();

    stream.Close();
    return msg;
}

1
Ries,我已经搜索了整整一天的解决方案,找到了许多部分工作的解析器和.NET库。你建议的Windows库百分之百地有效。这个答案应该排在第一位并高于其他答案。 - Tomas
6
可以在“添加引用”对话框的“COM”选项卡中添加对dll的引用。它列在“Microsoft CDO for Windows 2000 Library”下。正如Ries所说,它已经包含在IIS中了。 - niaher
3
我遇到了编译错误 - 类型 'CDO.MessageClass' 没有定义构造函数... 'ADOBD.StreamClass' 同理。你有什么想法吗? - Karan
看起来ADODB的Stream类会在流的开头添加2个字节进行编码,这会阻止CDO的Message类成功读取文件中的第一行头信息。为了避免这种情况,请在调用Open之前尝试将Stream.Type属性设置为StreamTypeEnum.adTypeBinary。 - Michael Petito
@MCOwen,请查看Github上的新示例项目:https://github.com/riesvriend/CDO-EML-Parsing-Sample - Ries Vriend
显示剩余5条评论

12

点击此链接获取一个好的解决方案:

该文章总结了4个步骤(以下第二步在文章中被省略,但是需要执行):

  1. 在Visual Studio的“添加引用”对话框的“COM”选项卡中找到“Microsoft CDO for Windows 2000 Library”,并将其添加为项目的引用。这将向您的项目中添加2个引用:“ADODB”和“CDO”。

  2. 禁用“ADODB”和“CDO”这两个引用的嵌入互操作类型功能。(引用 -> ADODB -> 属性 -> 将“嵌入互操作类型”设置为False,然后对CDO执行相同的操作)

  3. 将以下方法添加到您的代码中:

  4. protected CDO.Message ReadMessage(String emlFileName)
    {
        CDO.Message msg = new CDO.MessageClass();
        ADODB.Stream stream = new ADODB.StreamClass();
        stream.Open(Type.Missing, 
                       ADODB.ConnectModeEnum.adModeUnknown, 
                       ADODB.StreamOpenOptionsEnum.adOpenStreamUnspecified,                                                                         
                       String.Empty, 
                       String.Empty);
        stream.LoadFromFile(emlFileName);
        stream.Flush();
        msg.DataSource.OpenObject(stream, "_Stream");
        msg.DataSource.Save();
        return msg;
    }
    
  5. 通过传递您的eml文件的完整路径调用此方法,它返回的CDO.Message对象将具有您需要的所有解析信息,包括To、From、Subject和Body。


这个能否也传递包含在EML中的附件? - Rich

11

5
如果有人需要参考使用,请查看以下链接:https://github.com/fschwiet/ManyConsole/blob/master/SampleConsole/DumpEmlFiles.cs - Frank Schwieterman
3
现在它位于https://github.com/fschwiet/ManyConsole/blob/master/SampleConsole/DumpEmlFilesCommand.cs - Jeff Moser

4
您可能需要的是一款电子邮件/MIME解析器。解析所有标题字段并不难,但是分离各种MIME类型(如图像、附件、各种文本和HTML部分等)可能会变得非常复杂。
我们使用第三方工具,但是有许多C#工具/库可供使用。在Google中搜索免费的C#电子邮件MIME解析器。例如,我找到了这个:

http://www.codeproject.com/Articles/11882/Advanced-MIME-Parser-Creator-Editor http://www.lumisoft.ee/lswww/download/downloads/Net/info.txt


3

获得一个好的 MIME 解析器可能是可行的方法。您可以尝试使用免费的 MIME 解析器(例如 此处 的代码)但是来自代码作者的评论让我对代码质量产生了好奇。

我同时在开发 MSG 文件的包装类时开始了这个项目。难度有很大的区别。EML 包装类可能花了一天时间阅读规范并实现,而 MSG 包装类则花费了一周。

我确信您可以黑掉一个解析 95% 邮件正确的 MIME 解析器,仅需几天/几小时。但我也确信,在正确处理剩余 5% 的情况下会花费数月时间,其中包括处理 S/MIME(加密和签名电子邮件)、Unicode、由不良邮件客户端和服务器生成的畸形电子邮件、多种编码模式、国际化问题以及确保故意畸形的电子邮件不会使您的应用程序崩溃等。

如果您要解析的电子邮件来自单一来源,则快速且简单的解析器可能足够。如果需要解析来自未知来源的电子邮件,则需要更好的解决方案。

我建议使用我们的Rebex Secure Mail组件,但我相信其他供应商的组件也能得到不错的结果。
确保您选择的解析器在由MIME和IMAP RFC的共同作者Mike Crispin准备的臭名昭著的“Mime Torture Sample message”上正常工作。测试消息在MIME Explorer示例中显示,可以在安装包中下载
以下代码显示了如何读取和解析EML文件:
using Rebex.Mail;

MailMessage message = new MailMessage();
message.Load("file.eml");

1
“我也确信,解决剩下的5%需要数月时间。” - Binary Worrier

3
我刚开始使用Papercut的Mime部分来做这件事。乍一看,它似乎相当不错和简单。
    public void ProcessRawContents(string raw)
    {
        // NB: empty lines may be relevant for interpretation and for content !!
        var lRawLines = raw.Split(new []{"\r\n"}, StringSplitOptions.None);
        var lMailReader = new MimeReader(lRawLines);
        var lMimeEntity = lMailReader.CreateMimeEntity();
        MailMessageEx Email = lMimeEntity.ToMailMessageEx();
        // ...
    }

(当然,MailMessageEx 是从 MailMessage 派生而来的。)

2

尝试以下方法:

  • febootimail
  • SmtpExpress
  • LinkWS Newsletter Turbo
  • emlBridge - 将eml文件导入Outlook和几乎任何其他电子邮件客户端
  • Newsletter 2.1 Turbo
  • ThunderStor (emlResender)
  • Ruby(使用eml2mbox)。请参见jimbob method
  • Evolution - 创建新消息,附加eml文件,

编写一个程序:

解决方法:

  • $ cat mail.eml | mail -s -c 但无法解析标头或附件。
  • 将它们放入您的GMail中(Firefox会将它们保存为附件)

问题明确指出了C# .NET,但您在“尝试”部分的答案却指向非C#解决方案。 - CodeMonkeyKing

2

Aspose.Email for .NET

Aspose.Email for .NET是一个组件集,用于在您的.NET应用程序中处理电子邮件。它可以轻松处理多种电子邮件消息格式和消息存储文件(PST / OST),并具有发送和接收电子邮件消息的功能。

Aspose.Email使得不需要安装Microsoft Outlook就可以轻松创建、读取和操作多个消息格式,例如MSG、EML、EMLX和MHT文件。您不仅可以更改消息内容,还可以从消息对象中操作(添加、提取和删除)附件。您可以通过添加或删除收件人、更改主题或其他属性来自定义消息头。它还通过提供对其Mapi属性的访问,为您完全控制电子邮件消息。

无需Outlook即可读取C# Outlook MSG文件

MSGReader是一个C# .NET 4.0库,用于读取Outlook MSG和EML(Mime 1.0)文件。几乎支持Outlook中的所有常见对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接