Similar to the .msg file, which represents an individual MailItem in MS Outlook, the .eml format is employed by Outlook Express and Thunderbird to store messages. An EML file comprises the e-mail text, along with any attachments or files attached to it.
Because EML is not the default format of MS Outlook, it can pose a challenge to developers who want to work with .eml files via Outlook automation. Luckily, there are some very workable solutions to match your specific goals. In the “Saving an Email as an EML File in C#” tutorial, we learned how to programmatically create and save an EML-formatted e-mail by using the SmtpClient class. In today’s follow-up, we’ll write a C# console program to load and send .eml files by using the Microsoft.Office.Interop.Outlook library.
Installing the Microsoft.Office.Interop.Outlook Package
The NuGet Package Manager Console is built into Visual Studio on Windows, in versions 2012 and later. (It is not included with Visual Studio for Mac or Visual Studio Code.)
The console lets you use NuGet PowerShell commands to find, install, uninstall, and update NuGet packages. Using the console is necessary in cases where the Package Manager UI does not provide a way to perform an operation.
Here are the steps for adding the Microsoft.Office.Interop.Outlook package:
-
In Visual Studio, open the console by using the Tools > NuGet Package Manager > Package Manager Console command.
Figure 1: The NuGet Package ManagerThe NuGet prompt will launch:
Each package is licensed to you by its owner. NuGet is not responsible for, nor does it grant any licenses to, third-party packages. Some packages may include dependencies which are governed by additional licenses. Follow the package source (feed) URL to determine any dependencies. Package Manager Console Host Version 4.5.0.4685 Type 'get-help NuGet' to see all available NuGet commands. PM>
-
Enter “Install-Package Microsoft.Office.Interop.Outlook” at the prompt. You should see something like the following:
Attempting to gather dependency information for package 'Microsoft.Office.Interop.Outlook.15.0.4797.1003' with respect to project 'MailReadTests', targeting '.NETFramework,Version=v4.6.1' Gathering dependency information took 15.2 ms Attempting to resolve dependencies for package 'Microsoft.Office.Interop.Outlook.15.0.4797.1003' with DependencyBehavior 'Lowest' Resolving dependency information took 0 ms Resolving actions to install package 'Microsoft.Office .Interop.Outlook.15.0.4797.1003' Resolved actions to install package 'Microsoft.Office .Interop.Outlook.15.0.4797.1003' Retrieving package 'Microsoft.Office.Interop.Outlook 15.0.4797.1003' from 'nuget.org'. GET https://api.nuget.org/v3-flatcontainer/microsoft .office.interop.outlook/15.0.4797.1003/microsoft .office.interop.outlook.15.0.4797.1003.nupkg OK https://api.nuget.org/v3-flatcontainer/microsoft .office.interop.outlook/15.0.4797.1003/microsoft .office.interop.outlook.15.0.4797.1003.nupkg 741ms Installing Microsoft.Office.Interop.Outlook 15.0.4797.1003. Adding package 'Microsoft.Office.Interop.Outlook .15.0.4797.1003' to folder 'C:\Users\blackjacques \source\repos\MailReadTests\packages' Added package 'Microsoft.Office.Interop.Outlook.15.0 .4797.1003' to folder 'C:\Users\blackjacques\source \repos\MailReadTests\packages' Added package 'Microsoft.Office.Interop.Outlook .15.0.4797.1003' to 'packages.config' Successfully installed 'Microsoft.Office.Interop.Outlook 15.0.4797.1003' to MailReadTests Executing nuget actions took 5.56 sec Time Elapsed: 00:00:11.0316538 PM>
The Program Code
Our program will now be able to reference the Microsoft.Office.Interop.Outlook library to import an .eml file and send it.
Here are the using statements at the top of the Program.cs file for our C# .net console application. You can see the Microsoft.Office.Interop.Outlook library reference on the fourth line:
using System; using System.Linq; using System.Runtime.InteropServices; using Outlook = Microsoft.Office.Interop.Outlook; using System.Diagnostics; using System.Threading;
Referencing the Outlook Application
Using Outlook as our default e-mail program, we can start a new process via the ProcessStartInfo class. We then have to obtain a reference to the Outlook process to use it:
namespace MailReadTests { class Program { static void Main(string[] args) { Outlook.Application oOutlook = null; Outlook.NameSpace oNS = null; Object objsel = null; Outlook.MailItem oMail = null; string sendTo = @"guitargodofottawa@gmail.com"; string fl = @"I:\My Documents\articles\codeguru\C#\Saving an E-mail\SavedMail\test_sample_message.eml"; ProcessStartInfo psi = new ProcessStartInfo(fl); psi.UseShellExecute = true; Process.Start(psi); var process = Process.GetProcessesByName("OUTLOOK") .First(); Thread.Sleep(10); while (!process.HasExited) { try { oOutlook = (Outlook.Application)Marshal .GetActiveObject("Outlook.Application"); oNS = oOutlook.Session; break; } catch { oOutlook = null; } Thread.Sleep(10); } // Code to send e-mail will go here... oOutlook.Quit(); oOutlook = null; } } }
Sending the Email
We then can select the current item in the active inspector and send it just as we would with any Outlook MailItem:
Outlook.Inspectors inps = oOutlook.Inspectors; objsel = oOutlook.ActiveInspector().CurrentItem; if (objsel is Outlook.MailItem) { oMail = (Outlook.MailItem)objsel; oMail.To = sendTo; oMail.Send(); Console.WriteLine("email sent."); }
The Finished Product
Here is the complete code for the MailReadTests program:
using System; using System.Linq; using System.Runtime.InteropServices; using Outlook = Microsoft.Office.Interop.Outlook; using System.Diagnostics; using System.Threading; namespace MailReadTests { class Program { static void Main(string[] args) { Outlook.Application oOutlook = null; Outlook.NameSpace oNS = null; Object objsel = null; Outlook.MailItem oMail = null; string sendTo = @"guitargodofottawa@gmail.com"; string fl = @"I:\My Documents\articles\codeguru\C#\Saving an E-mail\SavedMail\test_sample_message.eml"; ProcessStartInfo psi = new ProcessStartInfo(fl); psi.UseShellExecute = true; Process.Start(psi); var process = Process.GetProcessesByName("OUTLOOK") .First(); Thread.Sleep(10); while (!process.HasExited) { try { oOutlook = (Outlook.Application)Marshal .GetActiveObject("Outlook.Application"); oNS = oOutlook.Session; break; } catch { oOutlook = null; } Thread.Sleep(10); } Outlook.Inspectors inps = oOutlook.Inspectors; objsel = oOutlook.ActiveInspector().CurrentItem; if (objsel is Outlook.MailItem) { oMail = (Outlook.MailItem)objsel; oMail.To = sendTo; oMail.Send(); Console.WriteLine("email sent."); } oOutlook.Quit(); oOutlook = null; } } }
Conclusion
In today’s article, we loaded an .eml file from the file system and sent it by using the Microsoft.Office.Interop.Outlook library. In addition to the objects that we worked with, there are also some third-party libraries worth exploring. One of these is Outlook redemption. I have used it in the past and have found it to be very useful. Another, which I have not used, but looks promising, is called MimeReader. Between them, you should be able to accomplish whatever you need to do.