OfficeIMO.Email
2.0.1
Prefix Reserved
dotnet add package OfficeIMO.Email --version 2.0.1
NuGet\Install-Package OfficeIMO.Email -Version 2.0.1
<PackageReference Include="OfficeIMO.Email" Version="2.0.1" />
<PackageVersion Include="OfficeIMO.Email" Version="2.0.1" />
<PackageReference Include="OfficeIMO.Email" />
paket add OfficeIMO.Email --version 2.0.1
#r "nuget: OfficeIMO.Email, 2.0.1"
#:package OfficeIMO.Email@2.0.1
#addin nuget:?package=OfficeIMO.Email&version=2.0.1
#tool nuget:?package=OfficeIMO.Email&version=2.0.1
OfficeIMO.Email
OfficeIMO.Email reads and writes persisted email and Outlook artifacts without MsgKit, MsgReader, OpenMcdf, RtfPipe, MimeKit, MailKit, or platform UI packages.
The package supports:
- EML and MIME messages, including multipart bodies, encoded headers, inline resources, attachments, and embedded messages
- Outlook MSG files with standard and named MAPI properties, legacy code pages, recipients, embedded messages, linked attachments, and OLE/custom-storage attachments
- MS-OXRTFCP compressed and uncompressed RTF bodies, including bounded expansion and checksum validation
- Outlook messages, appointments, contacts, tasks, journals, and sticky notes with typed read/write models
- TNEF payloads such as
winmail.dat - mboxo and mboxrd mailbox archives
- bounded synchronous and asynchronous reads, immutable reader configuration, cancellation, and structured diagnostics
- deterministic EML, MSG, TNEF, and mbox writing
MSG output includes the root storage identity, complete named-property forward and reverse mappings, and the compatibility metadata required by native Outlook. A document without an explicit date receives a deterministic creation-time fallback; set Date or MessageMetadata.CreatedDate when the real timestamp matters.
The package depends on OfficeIMO.Rtf, which owns RTF syntax and semantic conversion. OfficeIMO.Email directly declares Microsoft's code-page compatibility library because its MIME, MSG, and TNEF readers use legacy character encodings themselves. MSG compound storage is shared OfficeIMO source compiled into OfficeIMO.Email; it is not a public general-purpose CFB package. This keeps the product graph explicit without copying RTF or CFB logic into the facade.
Read and write a message
using OfficeIMO.Email;
EmailDocument message = EmailDocument.Load("message.msg");
Console.WriteLine(message.Subject);
Console.WriteLine(message.Body.Text);
message.Save("message.eml");
Save infers EML, MSG, or TNEF from .eml, .mime, .msg, .tnef, or winmail.dat. The convenience methods throw InvalidDataException instead of silently returning a partial document or output when an error diagnostic is produced. Use the explicit overload only when the destination name has another extension:
message.Save("artifact.bin", EmailFileFormat.OutlookMsg);
The async API has the same shape:
EmailDocument message = await EmailDocument.LoadAsync("message.msg", cancellationToken: cancellationToken);
await message.SaveAsync("message.eml", cancellationToken: cancellationToken);
Use EmailDocumentReader when the host needs custom limits, raw-source preservation, or structured diagnostics:
var options = new EmailReaderOptions(
maxInputBytes: 64L * 1024L * 1024L,
maxAttachmentBytes: 32L * 1024L * 1024L,
includeAttachmentContent: true);
EmailReadResult result = await new EmailDocumentReader(options).ReadAsync("message.msg");
foreach (EmailDiagnostic diagnostic in result.Diagnostics) {
Console.WriteLine($"{diagnostic.Severity}: {diagnostic.Code}: {diagnostic.Message}");
}
if (result.HasErrors) {
// The advanced API leaves recovery policy to the host.
}
The same model can be written as EML, MSG, or TNEF. Conversion is a load followed by a save:
EmailDocument.Load("source.eml").Save("converted.msg");
Read an mbox archive
An mbox file is an aggregate, so it has a dedicated reader rather than pretending to be one message:
var mailboxReader = new EmailMailboxReader();
EmailMailboxReadResult result = mailboxReader.Read("archive.mbox");
foreach (EmailMailboxEntry entry in result.Mailbox.Messages) {
Console.WriteLine($"{entry.EnvelopeSender}: {entry.Document.Subject}");
}
EmailMailboxWriter writes mboxo or mboxrd with deterministic envelope and escaping behavior.
Outlook item projections
MSG and TNEF properties remain available through MapiProperties even when no convenience property exists. Common Outlook item fields are also projected onto typed models:
EmailDocument item = EmailDocument.Load("meeting.msg");
if (item.OutlookItemKind == OutlookItemKind.Appointment && item.Appointment is not null) {
Console.WriteLine(item.Appointment.Start);
Console.WriteLine(item.Appointment.End);
Console.WriteLine(item.Appointment.Location);
}
Equivalent projections are available through Contact, Task, Journal, and Note.
Properties that do not have a convenience field remain available through MapiProperties. Standard, numeric named, and string named properties have public lookup helpers:
string? displayName = item.MapiProperties.GetMapiValue<string>(0x3001);
MapiProperty? custom = item.MapiProperties.GetMapiProperty(
new Guid("00062008-0000-0000-C000-000000000046"),
"CustomName");
RTF bodies
EmailBody.Rtf contains the byte-preserving RTF source decoded from PidTagRtfCompressed. The MSG and TNEF writers serialize an assigned RTF body with the MS-OXRTFCP compression format, and the reader accepts both the LZFu and MELA forms.
RTF syntax editing and semantic conversion belong to OfficeIMO.Rtf. Generate RTF through that package when the source contains characters that need RTF escapes. OfficeIMO.Reader will route an RTF-only email body through the registered OfficeIMO.Reader.Rtf handler; without that optional adapter, it preserves the RTF source and reports the fallback explicitly.
Protected Outlook messages
EmailDocument.Protection detects opaque and clear-signed S/MIME Outlook message classes and points to the original .p7m or .p7s attachment. It does not validate or decrypt that payload. Applications can pass Protection.PayloadAttachment.Content to MimeKit or another cryptographic owner when attachment content was retained.
EmailDocument protectedMessage = EmailDocument.Load("signed.msg");
if (protectedMessage.Protection.IsProtected) {
byte[]? cms = protectedMessage.Protection.PayloadAttachment?.Content;
// Mailozaurr or another host can process cms with its configured MimeKit context.
}
Resource limits
EmailReaderOptions is immutable and applies limits before retaining decoded content. It controls source size, header size and count, MIME part count and depth, per-attachment and aggregate attachment bytes, embedded-message depth, CFB directory entries, MAPI properties and decoded property bytes, and TNEF attributes.
Use includeAttachmentContent: false when only attachment metadata is needed. Parsing still validates the source structure, but decoded attachment payloads are not retained in the result model.
Reader integration
OfficeIMO.Reader recognizes .eml, .msg, .mbox, .mbx, .tnef, and winmail.dat. Its rich result includes envelope and Outlook metadata, structured diagnostics, materializable attachment assets, embedded messages, and chunks extracted from supported attachment formats.
using OfficeIMO.Reader;
OfficeDocumentReadResult result = OfficeDocumentReader.Default.ReadDocument("message.msg");
Console.WriteLine(result.Source.Title);
foreach (OfficeDocumentAsset attachment in result.Assets) {
Console.WriteLine($"{attachment.FileName}: {attachment.LengthBytes}");
}
Scope boundary
OfficeIMO.Email owns offline artifact parsing, serialization, and format-neutral Outlook data. It does not connect to mail servers, authenticate users, resolve certificates or keys, verify DKIM/ARC/PGP/S/MIME signatures, or decrypt protected messages. MailKit, MimeKit, and applications such as Mailozaurr remain the owners for those operations.
The package does not expose general-purpose CFB transactions and does not read PST or OST mailbox stores. Its compound implementation serves MSG and structured attachments only. Use EmailMailboxReader for mbox aggregates and a dedicated store API for PST/OST workflows.
For an exact pass-through of a signed or encrypted artifact, read with preserveRawSource: true and write with usePreservedRawSource: true. A structured rewrite can change MIME canonicalization and must not be treated as signature-preserving.
Dependency footprint
- External: No third-party email engine or Outlook interop.
System.Text.Encoding.CodePagessupplies legacy encodings. - OfficeIMO:
OfficeIMO.DrawingandOfficeIMO.Rtf. MIME, MSG/MAPI, TNEF, mbox, and compressed-RTF handling are first-party.
See the complete OfficeIMO package map for related formats and conversion paths.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 is compatible. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.7.2
- OfficeIMO.Drawing (>= 2.0.1)
- OfficeIMO.Rtf (>= 2.0.1)
- System.Text.Encoding.CodePages (>= 8.0.0)
-
.NETStandard 2.0
- OfficeIMO.Drawing (>= 2.0.1)
- OfficeIMO.Rtf (>= 2.0.1)
- System.Text.Encoding.CodePages (>= 8.0.0)
-
net10.0
- OfficeIMO.Drawing (>= 2.0.1)
- OfficeIMO.Rtf (>= 2.0.1)
-
net8.0
- OfficeIMO.Drawing (>= 2.0.1)
- OfficeIMO.Rtf (>= 2.0.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on OfficeIMO.Email:
| Package | Downloads |
|---|---|
|
OfficeIMO.Reader
Unified, read-only document extraction facade for OfficeIMO (Word/Excel/PowerPoint/Markdown/PDF) intended for AI ingestion. |
GitHub repositories
This package is not used by any popular GitHub repositories.