### MSGReader: 30-Second Start Examples Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/QUICK-REFERENCE.md Quickly extract MSG files to disk or read basic properties and EML files. These snippets demonstrate the most common use cases for getting started with MSGReader. ```csharp var reader = new Reader(); reader.ExtractToFolder("email.msg", "output"); using (var msg = new Storage.Message("email.msg")) { Console.WriteLine($"{msg.Sender?.EmailAddress}: {msg.Subject}"); } var eml = Mime.Message.Load(new FileInfo("email.eml")); Console.WriteLine($"From: {eml.Headers.From?.Address}"); ``` -------------------------------- ### Complete Configuration Setup Example Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/configuration.md A comprehensive example demonstrating the setup of a `Reader` instance with custom settings for logging, header style, culture, and extraction options. This snippet showcases various configuration properties and methods. ```csharp using var logStream = File.OpenWrite("extraction.log"); var reader = new Reader(logStream) { UseCustomHeaderStyle = true, InjectHeaderAsIFrame = false, CharsetDetectionEncodingConfidenceLevel = 0.85f, InstanceId = Environment.ProcessorCount.ToString() }; Reader.SetCustomHeaderStyle(@" table.MsgReaderHeader { font-family: 'Segoe UI', Arial, sans-serif; font-size: 11pt; width: 100%; } td.MsgReaderHeaderRowLabel { color: #333; background-color: #f0f0f0; font-weight: bold; padding: 4px 8px; } "); reader.SetCulture("de-DE"); var files = reader.ExtractToFolder( "email.msg", "output", ReaderHyperLinks.Both ); foreach (var file in files) Console.WriteLine($"Extracted: {file}"); ``` -------------------------------- ### VBA/VB6 Example: Using MSGReader Source: https://github.com/sicos1977/msgreader/wiki/How-to-use-this-component-from-VB6 Example of how to create an instance of the MSGReader object and use the ExtractToFolder method in VBA or VB6. ```vbscript dim msgreader set msgreader = createobject("MsgReader.Reader") msgreader.ExtractToFolder "[inputfile]", "[outputfolder]", [true or false] ``` -------------------------------- ### Install MSGReader via NuGet Source: https://github.com/sicos1977/msgreader/blob/master/MsgReader/README.md Installs the MSGReader package using the Package Manager Console in Visual Studio. ```powershell Install-Package MSGReader ``` -------------------------------- ### Use MSGReader from COM Source: https://github.com/sicos1977/msgreader/blob/master/MsgReader/README.md Example of calling MSGReader functionality from a COM-based language like VBScript. ```vbscript dim msgreader set msgreader = createobject("MsgReader.Reader") msgreader.ExtractToFolderFromCom "the msg file to read", "the folder where to place the extracted files" ``` -------------------------------- ### Handling Specialized Message Types Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/README.md Access specific properties for specialized message types like appointments, contacts, and tasks. This example shows how to retrieve the start date for appointments, primary email for contacts, and due date for tasks. ```csharp // Appointments var start = msg.Appointment?.Start; // Contacts var email = msg.Contact?.Email1EmailAddress; // Tasks var due = msg.Task?.DueDate; ``` -------------------------------- ### Extract all attachments to disk Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Attachment.md This example demonstrates how to iterate through all attachments of a message, extract their data, and save them to a specified directory on disk. ```APIDOC ## Extract all attachments to disk ### Usage Example ```csharp using (var msg = new Storage.Message("email.msg")) { string outputDir = "C:\\Attachments"; Directory.CreateDirectory(outputDir); foreach (var item in msg.Attachments) { if (item is Storage.Attachment att) { var filePath = Path.Combine(outputDir, att.FileName ?? "unnamed"); File.WriteAllBytes(filePath, att.Data); Console.WriteLine($"Extracted: {att.FileName}"); } } } ``` ``` -------------------------------- ### ConversationTopic Property Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Gets the subject topic of the conversation. Returns null if unavailable. ```csharp public string ConversationTopic { get; } ``` -------------------------------- ### Get Creation Time Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the UTC date and time when the message object was created. ```csharp public DateTimeOffset? CreationTime { get; } ``` -------------------------------- ### Get Original File Name Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the original filename of the MSG file. ```csharp public string FileName { get; } ``` -------------------------------- ### Get Follow-up Flag Information Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves follow-up flag information, including request text and due date. Null if no flag is set. ```csharp public Flag Flag { get; } ``` -------------------------------- ### Get Text Body Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the message body as plain text. This property will be null if no text body exists. ```csharp public string BodyText { get; } ``` -------------------------------- ### Filter inline vs. regular attachments Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Attachment.md This example shows how to filter attachments into two lists: one for inline images and another for regular file attachments. ```APIDOC ## Filter inline vs. regular attachments ### Usage Example ```csharp using (var msg = new Storage.Message("email.msg")) { var inlineImages = msg.Attachments .OfType() .Where(a => a.IsInline) .ToList(); var regularAttachments = msg.Attachments .OfType() .Where(a => !a.IsInline) .ToList(); Console.WriteLine($"Inline: {inlineImages.Count}, Regular: {regularAttachments.Count}"); } ``` ``` -------------------------------- ### Get Received By Information Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves information about who received the message. Null if unavailable. ```csharp public ReceivedBy ReceivedBy { get; } ``` -------------------------------- ### Get Message Type Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the type of the message (e.g., Email, Appointment, Contact). ```csharp public MessageType Type { get; } ``` -------------------------------- ### COM Usage for Extracting Files from MSG Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/QUICK-REFERENCE.md Example of using the MsgReader COM object from VB6 or VBScript to extract files from a .msg file to a specified folder. Includes error handling. ```vb Dim reader Set reader = CreateObject("MsgReader.Reader") Dim files files = reader.ExtractToFolderFromCom("email.msg", "output") If UBound(files) = -1 Then ' Error occurred WScript.Echo reader.GetErrorMessage() Else ' Success For Each file In files WScript.Echo file Next End If ``` -------------------------------- ### Get HTML Body Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the message body in HTML format. This property will be null if no HTML body exists. ```csharp public string BodyHtml { get; } ``` -------------------------------- ### Get Received On Date Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the UTC date and time when the message was received. This property will be null if not available. ```csharp public DateTimeOffset? ReceivedOn { get; } ``` -------------------------------- ### COM Error Handling with GetErrorMessage Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/errors.md This VB script example shows how to handle errors when using MsgReader from COM. It utilizes the ExtractToFolderFromCom method and checks the return value. If an error occurs (indicated by an empty array), GetErrorMessage() is called to retrieve the specific error message. ```vbscript Dim reader Set reader = CreateObject("MsgReader.Reader") Dim files files = reader.ExtractToFolderFromCom("email.msg", "output") If UBound(files) = -1 Then ' Error occurred - check error message WScript.Echo "Error: " & reader.GetErrorMessage() Else ' Success For Each file In files WScript.Echo "Extracted: " & file Next End If ``` -------------------------------- ### Get Task Information Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves task-specific information if the message is flagged as a task. Includes dates, status, and completion percentage. Null if not a task. ```csharp public Task Task { get; } ``` -------------------------------- ### Get Message Subject Prefix Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the subject prefix, such as 'RE:' or 'FW:'. This property will be null if no prefix exists. ```csharp public string SubjectPrefix { get; } ``` -------------------------------- ### Get Sender Information Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the sender's contact information, including Name and Email. Null if unavailable. ```csharp public Sender Sender { get; } ``` -------------------------------- ### Get Sent On Date Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the UTC date and time when the message was sent. Use `.ToLocalTime()` to convert to local time. ```csharp public DateTimeOffset? SentOn { get; } ``` -------------------------------- ### Delete Attachment and Save Modified Email Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/TECHNICAL-OVERVIEW.md This example shows how to open an email in read-write mode, delete a specific attachment by its index, and then save the modified email to a new file. Remember to dispose of the message object after use. ```csharp var msg = new Storage.Message("email.msg", FileAccess.ReadWrite); msg.DeleteAttachment(msg.Attachments[0]); msg.Save("email_cleaned.msg"); msg.Dispose(); ``` -------------------------------- ### Extract Appointment Details Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Loads a message and extracts appointment-specific details like start time, end time, location, and organizer if the message type is an appointment. Requires the 'Storage' namespace. ```csharp using (var msg = new Storage.Message("meeting.msg")) { if (msg.Type == MessageType.Appointment) { var appt = msg.Appointment; Console.WriteLine($"Meeting: {msg.Subject}"); Console.WriteLine($"Start: {appt.Start?.ToLocalTime()}"); Console.WriteLine($"End: {appt.End?.ToLocalTime()}"); Console.WriteLine($"Location: {appt.Location}"); Console.WriteLine($"Organizer: {msg.Sender?.EmailAddress}"); } } ``` -------------------------------- ### Retrieving Plain Text Body Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Mime.Message.md Get the first MessagePart containing the plain text body. The text content is returned as a byte array and can be decoded. ```csharp if (message.TextBody != null) { var text = Encoding.UTF8.GetString(message.TextBody.Body); Console.WriteLine(text); } ``` -------------------------------- ### Get Current Custom Header Style Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/TECHNICAL-OVERVIEW.md Retrieve the currently configured CSS string for custom header styling. This can be useful for inspection or modification. ```csharp Reader.GetCustomHeaderStyle(); // Get current CSS ``` -------------------------------- ### Accessing Message Body Structure Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Mime.Message.md Navigate the hierarchical message body structure starting from the root MessagePart. Check IsMultipart to determine if it contains child parts. ```csharp if (message.MessagePart != null) { Console.WriteLine($"Content-Type: {message.MessagePart.ContentType}"); if (message.MessagePart.IsMultipart) Console.WriteLine($"Parts: {message.MessagePart.MessageParts.Count}"); } ``` -------------------------------- ### Retrieving HTML Body Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Mime.Message.md Get the first MessagePart containing the HTML body. The HTML content is returned as a byte array and can be decoded. ```csharp if (message.HtmlBody != null) { var html = Encoding.UTF8.GetString(message.HtmlBody.Body); Console.WriteLine(html); } ``` -------------------------------- ### MSGReader: Extract Appointment Details Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/QUICK-REFERENCE.md Extracts appointment-specific details such as start time, end time, and location from an MSG file identified as a message type 'Appointment'. ```csharp using (var msg = new Storage.Message("meeting.msg")) { if (msg.Type == MessageType.Appointment) { var a = msg.Appointment; Console.WriteLine($"{msg.Subject}"); Console.WriteLine($" Start: {a.Start?.ToLocalTime()}"); Console.WriteLine($" End: {a.End?.ToLocalTime()}"); Console.WriteLine($" Location: {a.Location}"); } } ``` -------------------------------- ### Initialize Reader with Logging Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Reader.md Instantiate the Reader class, optionally providing a stream for logging extraction activities. This log stream can be shared across multiple extractions. ```csharp var reader = new Reader(); ``` -------------------------------- ### Basic MSG Extraction with Attachments Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Reader.md Demonstrates basic extraction of an MSG file to a folder, including its attachments. The first file in the returned array is the email body. ```csharp var reader = new Reader(); var files = reader.ExtractToFolder( "C:\\Email.msg", "C:\\ExtractedEmail" ); // files[0] = email body file // files[1..n] = attachment files ``` -------------------------------- ### Configure Global Log Stream Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/configuration.md Set up a global log stream at the Reader's construction to capture logs from all extractions. Ensure the stream is closed after all operations are complete. ```csharp // Global log stream (all extractions) var logStream = File.OpenWrite("extraction.log"); var reader = new Reader(logStream); reader.ExtractToFolder("email1.msg", "output1"); reader.ExtractToFolder("email2.msg", "output2"); // All logs written to extraction.log logStream.Close(); ``` -------------------------------- ### Get Message Importance Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the message importance level (Low=0, Normal=1, High=2). ```csharp public MessageImportance? Importance { get; } ``` -------------------------------- ### Load and Access MSG File Properties Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/TECHNICAL-OVERVIEW.md Demonstrates how to load an MSG file and access its subject, body, and sender's email address using the `Storage.Message` class. Ensure the `MSGReader` library is referenced. ```csharp using (var msg = new Storage.Message("email.msg")) { var subject = msg.Subject; var body = msg.BodyHtml ?? msg.BodyText; var sender = msg.Sender?.EmailAddress; } ``` -------------------------------- ### Get Last Modifier Name Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the name of the user who last modified the message. ```csharp public string LastModifierName { get; } ``` -------------------------------- ### Configure Per-Extraction Logging Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/configuration.md Enable logging for individual extractions by providing a separate log stream for each operation. This allows for granular log management. ```csharp var reader = new Reader(); // No global log // Extraction 1 with log using (var log1 = File.OpenWrite("email1.log")) { reader.ExtractToFolder("email1.msg", "output1", logStream: log1); } // Extraction 2 with different log using (var log2 = File.OpenWrite("email2.log")) { reader.ExtractToFolder("email2.msg", "output2", logStream: log2); } ``` -------------------------------- ### Create Inline Image References for HTML Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Attachment.md Replaces 'cid:' references in HTML body with file paths for inline images. ```csharp using (var msg = new Storage.Message("email.msg")) { var inlineAttachments = msg.Attachments .OfType() .Where(a => a.IsInline && !string.IsNullOrEmpty(a.ContentId)) .ToList(); var html = msg.BodyHtml ?? ""; foreach (var img in inlineAttachments) { // Replace CID reference with file path or base64 var cidRef = $"cid:{img.ContentId}"; var filePath = $"file:///{img.FileName}"; html = html.Replace(cidRef, filePath); } } ``` -------------------------------- ### Open MSG File with Different Access Modes Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/QUICK-REFERENCE.md Demonstrates how to open a .msg file in read-only or read-write mode. Also shows how to keep the underlying stream open after the message object is disposed. ```csharp // Read-only (default) var msg = new Storage.Message("file.msg"); // Read/Write (for modification) var msg = new Storage.Message("file.msg", FileAccess.ReadWrite); // Keep stream open after dispose var stream = File.OpenRead("file.msg"); var msg = new Storage.Message(stream, leaveStreamOpen: true); ``` -------------------------------- ### MSGReader: Essential Namespaces Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/QUICK-REFERENCE.md Import the necessary namespaces for using MSGReader's core functionalities, including reading, storage, MIME handling, and exceptions. ```csharp using MsgReader; using MsgReader.Outlook; using MsgReader.Mime; using MsgReader.Exceptions; ``` -------------------------------- ### Prefer File Paths Over Streams for Performance Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/configuration.md For optimal performance, use file paths directly with `ExtractToFolder` instead of streams. Using streams can lead to the entire file being loaded into memory, which is less efficient. ```csharp // Optimal: file path reader.ExtractToFolder("email.msg", "output"); // Less optimal: stream (entire file loaded to memory) using (var stream = File.OpenRead("email.msg")) { using (var msg = new Storage.Message(stream)) { // ... } } ``` -------------------------------- ### Get Recipients Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves a collection of all recipients (To, CC, BCC). See the Recipient class for details. ```csharp public ObservableCollection Recipients { get; } ``` -------------------------------- ### Get Last Modification Time Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the UTC date and time of the last modification to the message. ```csharp public DateTimeOffset? LastModificationTime { get; } ``` -------------------------------- ### Loading a Message from File, Stream, or Bytes Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Mime.Message.md Instantiate a Message object by loading from a FileInfo, Stream, or byte array. All Load methods parse the message synchronously. ```csharp var fileInfo = new FileInfo("email.eml"); var message = MsgReader.Mime.Message.Load(fileInfo); // Or from stream var stream = File.OpenRead("email.eml"); var message = MsgReader.Mime.Message.Load(stream); // Or from bytes var bytes = File.ReadAllBytes("email.eml"); var message = MsgReader.Mime.Message.Load(bytes); ``` -------------------------------- ### Get Message Subject Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the message subject line. This property will be null if the subject is empty. ```csharp public string Subject { get; } ``` -------------------------------- ### Catch ArgumentNullException Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/errors.md Catch this exception when a required parameter is unexpectedly null, often during file extraction setup. ```csharp try { reader.ExtractToFolder(null, "output"); // Throws ArgumentNullException } catch (ArgumentNullException ex) { Console.WriteLine($"Null argument: {ex.ParamName}"); } ``` -------------------------------- ### Accessing Attachments and Contact Photos Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Contact.md Demonstrates how to access attachments, including contact photos, from a contact object by leveraging its inheritance from Storage. ```csharp var attachments = contact.Attachments; var photo = attachments.OfType() .FirstOrDefault(a => a.IsContactPhoto); ``` -------------------------------- ### Using Message with IDisposable Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Demonstrates how to use the Message class with the IDisposable pattern for proper resource management when handling MSG files. ```csharp using (var msg = new MsgReader.Outlook.Storage.Message("path\to\email.msg")) { // Use message } ``` -------------------------------- ### Get Message Size Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the total message size in bytes. This property will be null if the size is unavailable. ```csharp public int? MessageSize { get; } ``` -------------------------------- ### Loading a Message from File Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Demonstrates how to load a Storage.Message object from a specified file path. This is the primary method for accessing MSG file content. ```APIDOC ## Load Message from File ### Description Loads a `Storage.Message` object from a given file path. This method allows direct access to the content of an MSG file. ### Method Static factory method on `Storage` class. ### Parameters #### Path Parameters - **messageFilePath** (string) - Required - The full path to the MSG file. - **fileAccess** (FileAccess) - Optional - Specifies the desired access mode for the file (default is `FileAccess.Read`). ### Response #### Success Response - Returns a `Storage.Message` object representing the loaded MSG file. ``` -------------------------------- ### Check Attachment Count and Size Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Attachment.md Calculates and displays the total number of attachments, their total size in KB, and the percentage each attachment contributes to the total size. ```csharp using (var msg = new Storage.Message("email.msg")) { var attachments = msg.Attachments.OfType().ToList(); Console.WriteLine($"Total attachments: {attachments.Count}"); long totalSize = 0; foreach (var att in attachments) { totalSize += att.Data.Length; } Console.WriteLine($"Total size: {totalSize / 1024.0:F2} KB"); foreach (var att in attachments) { var percent = (att.Data.Length / (double)totalSize) * 100; Console.WriteLine($" {att.FileName}: {percent:F1}%"); } } ``` -------------------------------- ### Get Message ID Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the RFC2822 message ID. This property may be null if the ID is not available. ```csharp public string Id { get; } ``` -------------------------------- ### Get Digital Signature Information Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the name of the person who digitally signed the message. Null if the message is unsigned. ```csharp public string SignedBy { get; } ``` -------------------------------- ### Load and Display Contact Information Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Contact.md Loads a contact from a .msg file and displays basic information such as display name, email, phone number, company, and title. Ensure the message type is Contact and the contact object is not null. ```csharp using (var msg = new Storage.Message("contact.msg")) { if (msg.Type == MessageType.Contact && msg.Contact != null) { var contact = msg.Contact; Console.WriteLine($"Name: {contact.DisplayName}"); Console.WriteLine($"Email: {contact.Email1EmailAddress}"); Console.WriteLine($"Phone: {contact.BusinessTelephoneNumber}"); Console.WriteLine($"Company: {contact.Company}"); Console.WriteLine($"Title: {contact.Function}"); } } ``` -------------------------------- ### Catch IOException Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/errors.md Handle general input/output errors, such as file access issues or disk space problems during read/write operations. ```csharp try { var files = reader.ExtractToFolder("email.msg", "output"); } catch (IOException ex) { Console.WriteLine($"I/O error: {ex.Message}"); } ``` -------------------------------- ### Get Message Categories Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves a list of message categories or tags assigned in Outlook. Null if no categories are assigned. ```csharp public List Categories { get; } ``` -------------------------------- ### Catch FileNotFoundException Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/errors.md Use this to handle cases where the input MSG or EML file does not exist or the path is invalid. ```csharp try { reader.ExtractToFolder("nonexistent.msg", "output"); } catch (FileNotFoundException ex) { Console.WriteLine($"File not found: {ex.FileName}"); } ``` -------------------------------- ### MSGReader: Configuration Options Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/QUICK-REFERENCE.md Configures MSGReader behavior, including custom header styles, iframe injection, character set detection confidence, localization, and logging. ```csharp // Global CSS for headers Reader.SetCustomHeaderStyle(@" table.MsgReaderHeader { border: 1px solid #ccc; } td { padding: 5px; } "); // Reader instance config var reader = new Reader { UseCustomHeaderStyle = true, InjectHeaderAsIFrame = false, CharsetDetectionEncodingConfidenceLevel = 0.85f }; // Localization reader.SetCulture("de-DE"); reader.SetCulture("nl-NL"); reader.SetCulture("fr-FR"); // Logging var reader = new Reader(File.OpenWrite("extraction.log")); ``` -------------------------------- ### Parse EML File and Access Headers/Body Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Mime.Message.md Loads an EML file and demonstrates how to access common email headers like From, To, Subject, and Date, as well as retrieving the message body. ```csharp var message = Mime.Message.Load(new FileInfo("email.eml")); // Access headers Console.WriteLine($"From: {message.Headers.From?.DisplayName} <{message.Headers.From?.Address}>"); Console.WriteLine($"To: {string.Join("; ", message.Headers.To.Select(h => h.Address))}"); Console.WriteLine($"Subject: {message.Headers.Subject}"); Console.WriteLine($"Date: {message.Headers.DateSent}"); // Get body string body = null; if (message.HtmlBody != null) body = Encoding.UTF8.GetString(message.HtmlBody.Body); else if (message.TextBody != null) body = Encoding.UTF8.GetString(message.TextBody.Body); Console.WriteLine(body); // List attachments if (message.Attachments != null) { foreach (var att in message.Attachments) Console.WriteLine($"Attachment: {att.FileName}"); } ``` -------------------------------- ### Load and Read Email Properties Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Loads an email message from a file and prints its sender, recipients, subject, date, body, and attachment filenames. Ensure the 'Storage' namespace is imported. ```csharp using (var msg = new Storage.Message("email.msg")) { Console.WriteLine($"From: {msg.Sender?.EmailAddress}"); Console.WriteLine($"To: {msg.GetEmailRecipients(RecipientType.To)}"); Console.WriteLine($"Subject: {msg.Subject}"); Console.WriteLine($"Date: {msg.SentOn?.ToLocalTime()}"); Console.WriteLine($"Body: {msg.BodyHtml ?? msg.BodyText}"); // List attachments foreach (var attachment in msg.Attachments) { if (attachment is Storage.Attachment att) Console.WriteLine($"Attachment: {att.FileName}"); } } ``` -------------------------------- ### Get Normalized Message Subject Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the message subject without any prefixes. This property will be null if the subject is empty. ```csharp public string SubjectNormalized { get; } ``` -------------------------------- ### Message Loading Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Mime.Message.md Demonstrates how to load an email message from different sources using the static Load methods of the Message class. ```APIDOC ## Message Loading ### Description Loads an email message from a file, stream, or byte array. ### Methods - `Load(FileInfo fileInfo)`: Loads a message from a file. - `Load(Stream stream)`: Loads a message from a stream. - `Load(byte[] messageBytes)`: Loads a message from a byte array. ### Example ```csharp // Load from FileInfo var fileInfo = new FileInfo("email.eml"); var messageFromFile = MsgReader.Mime.Message.Load(fileInfo); // Load from Stream using (var stream = File.OpenRead("email.eml")) { var messageFromStream = MsgReader.Mime.Message.Load(stream); } // Load from byte array var bytes = File.ReadAllBytes("email.eml"); var messageFromBytes = MsgReader.Mime.Message.Load(bytes); ``` ``` -------------------------------- ### Load and Access EML File Properties Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/TECHNICAL-OVERVIEW.md Illustrates loading an EML file and retrieving its subject and HTML body using the `Mime.Message.Load` method. This approach is suitable for standard email formats. ```csharp var message = Mime.Message.Load(new FileInfo("email.eml")); var subject = message.Headers.Subject; var html = message.HtmlBody?.Body; ``` -------------------------------- ### Prevent MRCannotRemoveAttachment Exception Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/errors.md Provides a preventative code example for MRCannotRemoveAttachment by ensuring the message file is opened with FileAccess.ReadWrite, not FileAccess.Read. ```csharp // Ensure file is opened with write access var msg = new Storage.Message("email.msg", FileAccess.ReadWrite); // NOT ReadOnly msg.DeleteAttachment(msg.Attachments[0]); msg.Save("output.msg"); ``` -------------------------------- ### Get Rendering Position for Inline Attachments Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the rendering position for inline attachments. Returns -1 if the attachment is not inline. ```csharp public int RenderingPosition { get; } ``` -------------------------------- ### Get Sender Representing Information Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the on-behalf-of sender information. Null if the message was not sent on behalf of another user. ```csharp public SenderRepresenting SenderRepresenting { get; } ``` -------------------------------- ### Appointment Property Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves details of an appointment, including start, end, location, recurrence, and organizer. Returns null if the message is not an appointment. ```csharp public Appointment Appointment { get; } ``` -------------------------------- ### Build vCard Format from Contact Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Contact.md Constructs a vCard (version 3.0) string representation of a contact, including display name, name, organization, title, email, and phone numbers. The generated vCard is then saved to a .vcf file. ```csharp using (var msg = new Storage.Message("contact.msg")) { var contact = msg.Contact; var vcard = new StringBuilder(); vcard.AppendLine("BEGIN:VCARD"); vcard.AppendLine("VERSION:3.0"); vcard.AppendLine($"FN:{contact.DisplayName}"); vcard.AppendLine($"N:{contact.SurName};{contact.GivenName}"); vcard.AppendLine($"ORG:{contact.Company}"); vcard.AppendLine($"TITLE:{contact.Function}"); vcard.AppendLine($"EMAIL:{contact.Email1EmailAddress}"); vcard.AppendLine($"TEL;TYPE=WORK,VOICE:{contact.BusinessTelephoneNumber}"); vcard.AppendLine($"TEL;TYPE=CELL:{contact.CellularTelephoneNumber}"); vcard.AppendLine("END:VCARD"); File.WriteAllText($"{contact.DisplayName}.vcf", vcard.ToString()); } ``` -------------------------------- ### Access Attachments via Message Object Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Attachment.md Demonstrates the standard way to access attachments by first opening a message file and then iterating through its Attachments collection. ```csharp // Access attachments via message using (var msg = new Storage.Message("email.msg")) { foreach (var item in msg.Attachments) { if (item is Storage.Attachment attachment) { // Use attachment } } } ``` -------------------------------- ### Register MsgReader.dll for COM Interop Source: https://github.com/sicos1977/msgreader/wiki/How-to-use-this-component-from-VB6 Register the MsgReader.dll file for COM interop using Regasm.exe. Ensure the Platform target is set to X86. ```bash Regasm.exe /codebase MsgReader.dll ``` -------------------------------- ### Extract EML File to Folder using Reader Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/TECHNICAL-OVERVIEW.md Demonstrates using the `Reader` class to extract an EML file to a folder. This leverages the high-level extraction capabilities of the library for standard email formats. ```csharp var reader = new Reader(); reader.ExtractToFolder("email.eml", "output"); ``` -------------------------------- ### Build Formatted Contact Address Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Contact.md Constructs and displays a formatted business address for a contact loaded from a .msg file. It uses a StringBuilder to append address components like street, city, state, postal code, and country. ```csharp using (var msg = new Storage.Message("contact.msg")) { var contact = msg.Contact; var address = new StringBuilder(); address.AppendLine(contact.BusinessAddressStreet); address.AppendLine($"{contact.BusinessAddressCity}, {contact.BusinessAddressStateOrProvince} {contact.BusinessAddressPostalCode}"); address.AppendLine(contact.BusinessAddressCountry); Console.WriteLine(address.ToString()); } ``` -------------------------------- ### Get Attachments and Embedded Messages Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves a collection of attachments and nested message objects. Use 'is Storage.Attachment' or 'is Storage.Message' to check the type. ```csharp public ObservableCollection Attachments { get; } ``` -------------------------------- ### Loading a Message from Stream Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Shows how to load a Storage.Message object from a stream. This is useful for processing MSG data from sources other than files. ```APIDOC ## Load Message from Stream ### Description Loads a `Storage.Message` object from a stream. This method is suitable for scenarios where the MSG data is available in memory or from a network stream. ### Method Static factory method on `Storage` class. ### Parameters #### Path Parameters - **messageStream** (Stream) - Required - The stream containing the MSG file data. - **fileAccess** (FileAccess) - Optional - Specifies the desired access mode for the stream (default is `FileAccess.Read`). - **leaveStreamOpen** (bool) - Optional - Determines whether the stream should remain open after the message is loaded (default is `false`). ### Response #### Success Response - Returns a `Storage.Message` object representing the loaded MSG data. ``` -------------------------------- ### Catch DirectoryNotFoundException Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/errors.md Catch this exception when the specified output folder path is missing or invalid. ```csharp try { reader.ExtractToFolder("email.msg", "C:\\nonexistent\\folder"); } catch (DirectoryNotFoundException ex) { Console.WriteLine($"Directory not found: {ex.Message}"); } ``` -------------------------------- ### Load Message from File Path Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Loads a Storage.Message object from a specified file path. Supports read-only or read/write access. ```csharp public static Storage.Message Load(string messageFilePath, FileAccess fileAccess = FileAccess.Read) ``` -------------------------------- ### Attachment Handling Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/README.md Iterates through message attachments and saves them to disk. ```APIDOC ## Storage.Message.Attachments ### Description Accesses the collection of attachments associated with a message. ### Properties - **Attachments** (IList) - A list of attachments. ### Usage ```csharp foreach (var item in msg.Attachments) { if (item is Storage.Attachment att) File.WriteAllBytes(att.FileName, att.Data); } ``` ### Attachment Properties - **FileName** (string) - The name of the attachment file. - **Data** (byte[]) - The binary data of the attachment. ``` -------------------------------- ### Extract Email Body from Stream with Charset Handling Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Mime.Message.md Loads an email message from a stream and demonstrates how to correctly decode the HTML body, assuming UTF-8 encoding. ```csharp using var stream = File.OpenRead("email.eml"); var message = Mime.Message.Load(stream); // HtmlBody is UTF-8 encoded byte array if (message.HtmlBody != null) { var html = Encoding.UTF8.GetString(message.HtmlBody.Body); // Process HTML... } ``` -------------------------------- ### Get Message Importance Text Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves a localized text representation of the message importance (e.g., 'Low', 'Normal', 'High'). Returns an empty string if not set. ```csharp public string ImportanceText { get; } ``` -------------------------------- ### EML Reading - MIME Message Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/README.md Illustrates how to load and read an EML (MIME) file using the Mime.Message class. ```APIDOC ## Mime.Message.Load ### Description Loads and parses an EML (MIME) file. ### Method ``` Mime.Message.Load(FileInfo fileInfo) ``` ### Parameters - **fileInfo** (FileInfo) - Required - Information about the EML file. ### Response #### Success Response - **Headers** (MimeHeaders) - The headers of the MIME message. - **HtmlBody** (MimeBody) - The HTML body part of the message. - **Headers.Subject** (string) - The subject from the message headers. ``` -------------------------------- ### Get Custom Header CSS Style Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/QUICK-REFERENCE.md Retrieves the CSS style used for custom headers, either the currently configured style or the default if none is set. ```csharp var css = Reader.GetCustomHeaderStyle(); // Current or default ``` -------------------------------- ### Register Code Pages for .NET Standard Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/configuration.md For .NET Standard projects, explicitly register the `CodePagesEncodingProvider` to ensure support for a wider range of character encodings. This is typically done automatically in the Reader constructor for .NET Standard environments. ```csharp // This is done automatically in Reader constructor for NETSTANDARD var encodingProvider = CodePagesEncodingProvider.Instance; Encoding.RegisterProvider(encodingProvider); var reader = new Reader(); // Now supports Asian, Eastern European, and other code pages ``` -------------------------------- ### Get RTF Body Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves the message body in RTF format. If HTML is encapsulated in RTF, this returns the RTF-decoded HTML content. Null if no RTF body exists. ```csharp public string BodyRtf { get; } ``` -------------------------------- ### MSGReader Public API Modules Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/GENERATION-SUMMARY.txt The MSGReader library exposes its functionality through several API reference modules, each focusing on a specific aspect of file reading and storage. These modules provide access to core functionalities for reading messages, contacts, and attachments from MSG files, as well as parsing EML/MIME messages. ```APIDOC ## API Reference Modules ### Reader.md **Description**: Provides the main extraction API for MSGReader. This module contains constructors, methods, and properties for initiating and managing file reading operations. ### Storage.Message.md **Description**: Focuses on the MSG message reader. This module details the API for accessing and reading the content of MSG messages, including a complete list of properties. ### Storage.Contact.md **Description**: Covers contact cards. This module describes the API for reading contact information, including over 50 distinct fields. ### Storage.Attachment.md **Description**: Deals with file attachments. This module outlines the API for extracting attachments and their associated metadata from MSG files. ### Mime.Message.md **Description**: Handles EML/MIME message parsing. This module provides the API for parsing email messages in EML and MIME formats. ``` -------------------------------- ### Retrieve Current Custom Header CSS Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/configuration.md Get the currently applied custom CSS stylesheet for email headers using the GetCustomHeaderStyle method. This returns the CSS string that was previously set. ```csharp var currentCSS = Reader.GetCustomHeaderStyle(); ``` -------------------------------- ### List All Available Phone Numbers for a Contact Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Contact.md Retrieves and lists various phone numbers associated with a contact, including business, home, mobile, and fax numbers. It filters out any empty entries before printing. ```csharp using (var msg = new Storage.Message("contact.msg")) { var contact = msg.Contact; var phones = new Dictionary { { "Business", contact.BusinessTelephoneNumber }, { "Business 2", contact.BusinessTelephoneNumber2 }, { "Business Fax", contact.BusinessFaxNumber }, { "Home", contact.HomeTelephoneNumber }, { "Home 2", contact.HomeTelephoneNumber2 }, { "Home Fax", contact.HomeFaxNumber }, { "Mobile", contact.CellularTelephoneNumber }, { "Car", contact.CarTelephoneNumber }, { "Assistant", contact.AssistantTelephoneNumber }, { "Company Main", contact.CompanyMainTelephoneNumber }, }; foreach (var phone in phones.Where(p => !string.IsNullOrEmpty(p.Value))) { Console.WriteLine($"{phone.Key}: {phone.Value}"); } } ``` -------------------------------- ### Navigate Multipart Message Structure Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Mime.Message.md Recursively traverses the MIME structure of a message to identify content types, filenames of attachments, and nested parts. ```csharp var message = Mime.Message.Load(new FileInfo("email.eml")); void PrintParts(MessagePart part, int depth = 0) { var indent = new string(' ', depth * 2); Console.WriteLine($"{indent}{part.ContentType}"); if (part.IsMultipart && part.MessageParts != null) { foreach (var subpart in part.MessageParts) PrintParts(subpart, depth + 1); } else if (part.IsAttachment) { Console.WriteLine($"{indent} -> {part.FileName} ({part.Body.Length} bytes)"); } } PrintParts(message.MessagePart); ``` -------------------------------- ### HTML Notes Property Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Contact.md Represents notes or comments in HTML format. This property is null if no notes are present. ```csharp public string Html { get; } ``` -------------------------------- ### Extract Files from Attachments Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/TECHNICAL-OVERVIEW.md This snippet iterates through all attachments in an email and saves each one to disk. Ensure the output directory exists and you have write permissions. ```csharp using (var msg = new Storage.Message("email.msg")) { foreach (var item in msg.Attachments) { if (item is Storage.Attachment att) { File.WriteAllBytes( $"C:\\Output\\{att.FileName}", att.Data ); } } } ``` -------------------------------- ### MSG Reading - High-level Extraction Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/README.md Demonstrates high-level extraction of an MSG file to a specified folder using the Reader class. ```APIDOC ## Reader.ExtractToFolder ### Description High-level extraction of an Outlook MSG file to a specified folder, with options for handling hyperlinks. ### Method ``` Reader.ExtractToFolder(string filePath, string folderPath, ReaderHyperLinks linkType) ``` ### Parameters - **filePath** (string) - Required - Path to the MSG file. - **folderPath** (string) - Required - Path to the output folder. - **linkType** (ReaderHyperLinks) - Required - Specifies how to handle hyperlinks. ``` -------------------------------- ### Attachment Handling Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/README.md Iterate through attachments of a message and save them to disk. This snippet demonstrates how to check if an item is a Storage.Attachment and write its data to a file. ```csharp foreach (var item in msg.Attachments) { if (item is Storage.Attachment att) File.WriteAllBytes(att.FileName, att.Data); } ``` -------------------------------- ### Extract Task Details Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Loads a message and extracts task-specific details including status, percentage complete, due date, and owner. Assumes the message is a task type. Ensure 'Storage' namespace is available. ```csharp using (var msg = new Storage.Message("task.msg")) { var task = msg.Task; Console.WriteLine($"Task: {msg.Subject}"); Console.WriteLine($"Status: {task.StatusText}"); Console.WriteLine($"% Complete: {(task.PercentageComplete * 100)}%"); Console.WriteLine($"Due: {task.DueDate?.ToLocalTime()}"); Console.WriteLine($"Owner: {task.Owner}"); } ``` -------------------------------- ### MSGReader: Error Handling Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/QUICK-REFERENCE.md Implements robust error handling for common MSGReader exceptions, including unsupported file types, file not found, invalid signatures, and I/O errors. ```csharp try { reader.ExtractToFolder("email.msg", "output"); } catch (MRFileTypeNotSupported ex) { Console.WriteLine($"Not an MSG/EML file: {ex.Message}"); } catch (FileNotFoundException ex) { Console.WriteLine($"File not found: {ex.FileName}"); } catch (MRInvalidSignedFile ex) { Console.WriteLine($"Bad signature: {ex.Message}"); } catch (IOException ex) { Console.WriteLine($"I/O error (locked, permission): {ex.Message}"); } ``` -------------------------------- ### Set UI Culture for Localization Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/configuration.md Configure the UI culture for header text localization by calling `SetCulture` with the desired culture code. The library falls back to system culture or en-US if the specified culture is unavailable. ```csharp var reader = new Reader(); reader.SetCulture("nl-NL"); // Dutch reader.SetCulture("de-DE"); // German reader.SetCulture("fr-FR"); // French reader.SetCulture("zh-CN"); // Simplified Chinese reader.SetCulture("en-US"); // English (US) reader.ExtractToFolder("email.msg", "output"); ``` -------------------------------- ### GetOwnerReactionStringList Method Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Retrieves a list of emoji reactions made by the message owner or sender. Returns null if no reactions are present. ```csharp public List GetOwnerReactionStringList() ``` -------------------------------- ### Save Method Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Saves the message, including any modifications such as deleted attachments, to a new file path. ```csharp public void Save(string outputFile) ``` -------------------------------- ### Comprehensive .NET Error Handling Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/errors.md This snippet demonstrates a robust try-catch block for handling various exceptions that may occur during file extraction with MsgReader in a .NET environment. It catches specific exceptions like ArgumentNullException, FileNotFoundException, and MRFileTypeNotSupported, as well as general IOExceptions and unexpected exceptions. ```csharp var reader = new Reader(); try { var files = reader.ExtractToFolder( inputFile, outputFolder, ReaderHyperLinks.Both ); Console.WriteLine($"Extracted {files.Length} files:"); foreach (var file in files) Console.WriteLine($" - {file}"); } catch (ArgumentNullException ex) { Console.WriteLine($"Invalid argument: {ex.ParamName}"); } catch (FileNotFoundException ex) { Console.WriteLine($"Input file not found: {ex.FileName}"); } catch (DirectoryNotFoundException ex) { Console.WriteLine($"Output directory not found: {ex.Message}"); } catch (MRFileTypeNotSupported ex) { Console.WriteLine($"File type not supported: {ex.Message}"); } catch (MRInvalidSignedFile ex) { Console.WriteLine($"Invalid signature on message: {ex.Message}"); } catch (IOException ex) { Console.WriteLine($"I/O error: {ex.Message}"); } catch (Exception ex) { Console.WriteLine($"Unexpected error: {ex.GetType().Name} - {ex.Message}"); } ``` -------------------------------- ### MSGReader: Read EML File Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/QUICK-REFERENCE.md Loads and reads properties from an EML file, including headers, subject, sender, recipients, date, body content (HTML/text), and attachments. ```csharp var msg = Mime.Message.Load(new FileInfo("email.eml")); msg.Headers.Subject msg.Headers.From?.Address msg.Headers.To[0].Address msg.Headers.DateSent var html = msg.HtmlBody?.Body; var text = msg.TextBody?.Body; Encoding.UTF8.GetString(msg.HtmlBody.Body) foreach (var att in msg.Attachments) { File.WriteAllBytes(att.FileName, att.Body); } ``` -------------------------------- ### EML Reading (MIME Format) Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/README.md Load and parse EML (MIME) files using the Mime.Message class. This allows access to headers, subject, and HTML body content. ```csharp var msg = Mime.Message.Load(new FileInfo("email.eml")); var subject = msg.Headers.Subject; var html = Encoding.UTF8.GetString(msg.HtmlBody?.Body); ``` -------------------------------- ### Read Email Properties Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/TECHNICAL-OVERVIEW.md This snippet demonstrates how to open a .msg file and read common email properties such as sender, recipients, subject, and sent date. It also checks for the presence of attachments. ```csharp using (var msg = new Storage.Message("email.msg")) { Console.WriteLine($"From: {msg.Sender?.EmailAddress}"); Console.WriteLine($"To: {msg.GetEmailRecipients(RecipientType.To)}"); Console.WriteLine($"Subject: {msg.Subject}"); Console.WriteLine($"Date: {msg.SentOn?.ToLocalTime()}"); if (msg.Attachments?.Count > 0) Console.WriteLine($"Attachments: {msg.Attachments.Count}"); } ``` -------------------------------- ### MSGReader Storage Class Hierarchy Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/TECHNICAL-OVERVIEW.md Visual representation of the inheritance structure for MSG file handling classes within the `Storage` namespace. This hierarchy outlines the base `Storage` class and its specialized derived types. ```csharp Storage (abstract base, handles MAPI/file I/O) ├── Message ├── Attachment ├── Contact ├── Appointment ├── Task ├── Sender ├── Recipient ├── ReceivedBy ├── Flag ├── Reaction └── ... (10+ other types) ``` -------------------------------- ### Format Recipient Lists with Hyperlinks Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Mime.Message.md Formats recipient lists into an HTML string, with each email address wrapped in a clickable 'mailto:' hyperlink. ```csharp var reader = new Reader(); var message = Mime.Message.Load(new FileInfo("email.eml")); var toHtml = message.GetEmailAddresses( message.Headers.To, convertToHref: true, htmlFormat: true ); // Result: "user1@example.com; user2@example.com" ``` -------------------------------- ### MSGReader: Extract Task Details Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/QUICK-REFERENCE.md Extracts task-related details such as status, percentage complete, and due date from an MSG file identified as a task. ```csharp using (var msg = new Storage.Message("task.msg")) { var t = msg.Task; Console.WriteLine($"{msg.Subject}"); Console.WriteLine($" Status: {t.StatusText}"); Console.WriteLine($" % Complete: {t.PercentageComplete * 100}%"); Console.WriteLine($" Due: {t.DueDate?.ToLocalTime()}"); } ``` -------------------------------- ### Load Message from Stream Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Loads a Storage.Message object from a stream. Allows control over whether the stream is left open after loading. ```csharp public static Storage.Message Load(Stream messageStream, FileAccess fileAccess = FileAccess.Read, bool leaveStreamOpen = false) ``` -------------------------------- ### SignedOn Property Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Storage.Message.md Represents the UTC date and time of a digital signature. It is null if the message is unsigned. ```csharp public DateTimeOffset? SignedOn { get; } ``` -------------------------------- ### Extract Message to Folder (COM Visible) Source: https://github.com/sicos1977/msgreader/blob/master/_autodocs/api-reference/Reader.md A COM-visible wrapper for ExtractToFolder that returns error messages via GetErrorMessage() instead of throwing exceptions. Useful for COM interop scenarios. ```csharp var reader = new Reader(); var files = reader.ExtractToFolderFromCom("message.msg", "output", ReaderHyperLinks.Email, "en-US"); if (files.Length == 0) Console.WriteLine(reader.GetErrorMessage()); ```