Open the file with Mail.Open and take its one item: you get the subject, sender, recipients, date, bodies and attachments as plain .NET values. No Outlook, COM or native library is involved. The program below reads a public test message from Apache POI.
dotnet new console -o ReadMsg && cd ReadMsg dotnet add package RecursiveAI.OneMail --version 0.2.0-preview.2 curl -LO https://raw.githubusercontent.com/apache/poi/REL_5_4_1/test-data/hsmf/attachment_test_msg.msg
OneMail is a preview, so dotnet add package needs --version or --prerelease. Put this in Program.cs and run dotnet run:
using RecursiveAI.OneMail; // Mail.Open reads the format from the bytes, not the extension: // .msg, .oft, .eml, .pst and mbox files all open the same way using MailContainer file = Mail.Open("attachment_test_msg.msg"); IMailItem msg = file.Enumerate().First(); Console.WriteLine($"Format: {file.Format}"); Console.WriteLine($"Subject: {msg.Subject}"); Console.WriteLine($"From: {msg.From.FirstOrDefault()}"); Console.WriteLine($"To: {string.Join(", ", msg.ToRecipients)}"); Console.WriteLine($"Sent: {msg.Sent?.Value:u}"); Console.WriteLine($"Text body: {msg.TextBody?.ReadText().Trim()}"); Console.WriteLine($"HTML body: {msg.HtmlBody?.ReadText().Length} characters"); Console.WriteLine($"RTF body: {(msg.RtfBody is null ? "no" : "yes")}"); foreach (IMailAttachment a in msg.Attachments) Console.WriteLine($"Attachment: {a.FileName} ({a.Size:N0} bytes)");
Format: Msg Subject: test pièce jointe 1 From: Nicolas1 23456 <[email protected]> To: '[email protected]' <[email protected]> Sent: 2009-04-22 14:36:33Z Text body: contenu HTML body: 1033 characters RTF body: yes Attachment: test-unicode.doc (24,064 bytes) Attachment: pj1.txt (89 bytes)
Mail.Open reads the first bytes to decide the format, so the same call opens .oft templates, .eml files, PST stores and mbox files. The items share one interface, IMailItem.
The bodies
An Outlook message can carry plain text, HTML and RTF. TextBody, HtmlBody and RtfBody give each one that is present. When Outlook stored the HTML wrapped inside the RTF body, as in this file, HtmlBody returns that HTML. Call ReadText() for a string, or Open() for a stream.
Attachments
Attachments lists files and embedded messages in order. Size is the decoded size and Open() returns the content. An attached message has Embedded set to an IMailItem you can read the same way. To save the files, see Extract attachments from email.
Limits
- A preview. 0.2.0-preview.2: the API can change before 1.0.
- Reading only. OneMail can’t write MSG files yet. To get a file other programs read, convert it to EML.
- Damaged files. The project’s own fidelity table lists this gap: “two fuzz-minimised files from the corpus are refused by the compound file reader (typed defect)”.
- RTF-only messages. Plain RTF bodies (not wrapped HTML or text) aren’t converted to HTML.
RtfBodystill gives you the RTF. - Exchange senders. A sender with only an Exchange (X.500) address and no SMTP form has an empty
Address;NameandX500Addressare still set.
Everything checked, and every known gap: Fidelity and known gaps. How the format is read: MSG and OFT.