Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Send Outlook Email with Multiple Attachments, Recipients and Signature of the Default Account

0.00/5 (No votes)
4 May 2014 1  
A class for sending emails with Outlook using the default Outlook Account. It includes adding multiple attachments and recipients and choosing to use the default email signature or not.

Introduction

During development, everyone comes to the point where he/she has to send email with the application. It is very easy but sometimes there are tasks that can make you crazy. For example, setting a signature in an Outlook email. It's truly a tricky one. ;)

Background

After lots of time searching how to do things with Outlook mailing, I would like to share my final class for sending emails. Besides that, there are also lots of other cool things you can do with Outlook but that should have a separate article on its own.

The class uses an email validation method that validates email addresses. I found this part here. Just modified it to fit in a static class:

private static bool invalid = false;

public static bool IsValidEmailString(string strIn)
{
    invalid = false;
    if (String.IsNullOrEmpty(strIn))
        return false;
        
    // Use IdnMapping class to convert Unicode domain names. 
    try
    {
        strIn = Regex.Replace(strIn, @"(@)(.+)$", DomainMapper,
                              RegexOptions.None, TimeSpan.FromMilliseconds(200));
    }
    catch (RegexMatchTimeoutException)
    {
        return false;
    }
    
    if (invalid)
        return false;
        
    // Return true if strIn is in valid e-mail format. 
    try
    {
        return Regex.IsMatch(strIn,
              @"^(?("")(""[^""]+?""@)|
              (([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])quot; +
              @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9]{2,24}))$",
              RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));
    }
    catch (RegexMatchTimeoutException)
    {
        return false;
    }
} 

For this part, I won't write any explanation because it is explained in the above link.

And there we are. Already at the main method that sends the email. ;)

public static void SendEmail(string[] to, string subject, string body, string[] attachments, bool display = true, bool useSignature = true)
        {
            //Create main objects
            Outlook.Application outlookApp = new Outlook.Application();
            Outlook.NameSpace nameSpace = outlookApp.GetNamespace("MAPI");
            Outlook.MAPIFolder mapiFolder = nameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);
            Outlook.MailItem mailItem = mapiFolder.Items.Add(Outlook.OlItemType.olMailItem) as Outlook.MailItem;
            Outlook.Recipients recipients = mailItem.Recipients as Outlook.Recipients;

            //Set email subject
            mailItem.Subject = subject;

            //Set email recipients
            foreach (string tempTO in to)
            {
                //Set recipient only if it is an Valid email address
                if (tempTO != string.Empty && IsValidEmailString(tempTO))
                    recipients.Add(tempTO);
            }
            //Resolve recipients
            recipients.ResolveAll();

            //Add email attachments if there are some
            foreach (string attachment in attachments)
            {
                //Add attachment only if the attachment path really exists
                if (File.Exists(attachment))
                    mailItem.Attachments.Add(attachment);
            }

            //Get the signature in the email body
            mailItem.GetInspector.Activate();
            var signature = mailItem.HTMLBody;

            //Set the email body
            mailItem.HTMLBody = body;

            //If useSignature is true add the signature to the body
            if (useSignature)
                mailItem.HTMLBody += signature;

            //Display or directly send email depending on if there are recipients or the bool display
            if (mailItem.Recipients.Count == 0 || display)
            {
                mailItem.Display();
            }
            else
            {
                mailItem.Send();
            }
        } 

Every line of code is commented. The tricky part is to get the signature of the default user and add it to the email body. With GetInspector.Active(), we set the default signature to the mailItem HTML body. After that, we just save the HTML body to a var. After that, we can add the signature to the body with our text in it.

Besides this method, we can make 2 others that we can use for simple email actions like sending just an email without attachments or with just one recipient and one attachment:

        public static void SendEmail(string to, string subject, string body, string attachment, bool display = true, bool useSignature = true)
        {
            SendEmail(new string[] { to }, subject, body, new string[] { attachment }, display, useSignature);
        }

        public static void SendEmail(string to, string subject, string body, bool display = true, bool useSignature = true)
        {
            SendEmail(to, subject, body, null, display, useSignature);
        } 

Let's now take a look at the whole class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Net;
using System.Net.Mail;
using Outlook = Microsoft.Office.Interop.Outlook;
using System.Diagnostics;
using System.IO;

namespace ICS.EnterpriseResourcePlaning
{
    public static class Email
    {
        private static bool invalid = false;

        public static bool IsValidEmailString(string strIn)
        {
            invalid = false;
            if (String.IsNullOrEmpty(strIn))
                return false;

            // Use IdnMapping class to convert Unicode domain names. 
            try
            {
                strIn = Regex.Replace(strIn, @"(@)(.+)$", DomainMapper,
                                      RegexOptions.None, TimeSpan.FromMilliseconds(200));
            }
            catch (RegexMatchTimeoutException)
            {
                return false;
            }

            if (invalid)
                return false;

            // Return true if strIn is in valid e-mail format. 
            try
            {
                return Regex.IsMatch(strIn,
                      @"^(?("")(""[^""]+?""@)|
                      (([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" +
                      @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9]{2,24}))$",
                      RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));
            }
            catch (RegexMatchTimeoutException)
            {
                return false;
            }
        }

        private static string DomainMapper(Match match)
        {
            // IdnMapping class with default property values.
            IdnMapping idn = new IdnMapping();

            string domainName = match.Groups[2].Value;
            try
            {
                domainName = idn.GetAscii(domainName);
            }
            catch (ArgumentException)
            {
                invalid = true;
            }
            return match.Groups[1].Value + domainName;
        }

        public static void SendEmail(string[] to, string subject, 
        string body, string[] attachments, bool display = true, bool useSignature = true)
        {
            //Create main objects
            Outlook.Application outlookApp = new Outlook.Application();
            Outlook.NameSpace nameSpace = outlookApp.GetNamespace("MAPI");
            Outlook.MAPIFolder mapiFolder = nameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);
            Outlook.MailItem mailItem = mapiFolder.Items.Add(Outlook.OlItemType.olMailItem) as Outlook.MailItem;
            Outlook.Recipients recipients = mailItem.Recipients as Outlook.Recipients;

            //Set email subject
            mailItem.Subject = subject;

            //Set email recipients
            foreach (string tempTO in to)
            {
                //Set recipient only if it is an Valid email address
                if (tempTO != string.Empty && IsValidEmailString(tempTO))
                    recipients.Add(tempTO);
            }
            //Resolve recipients
            recipients.ResolveAll();

            //Add email attachments if there are some
            foreach (string attachment in attachments)
            {
                //Add attachment only if the attachment path really exists
                if (File.Exists(attachment))
                    mailItem.Attachments.Add(attachment);
            }

            //Get the signature in the email body
            mailItem.GetInspector.Activate();
            var signature = mailItem.HTMLBody;

            //Set the email body
            mailItem.HTMLBody = body;

            //If useSignature is true add the signature to the body
            if (useSignature)
                mailItem.HTMLBody += signature;

            //Display or directly send email depending on if there are recipients or the bool display
            if (mailItem.Recipients.Count == 0 || display)
            {
                mailItem.Display();
            }
            else
            {
                mailItem.Send();
            }
        }

        public static void SendEmail(string to, string subject, string body, 
        string attachment, bool display = true, bool useSignature = true)
        {
            SendEmail(new string[] { to }, subject, body, new string[] { attachment }, display, useSignature);
        }

        public static void SendEmail(string to, string subject, 
        string body, bool display = true, bool useSignature = true)
        {
            SendEmail(to, subject, body, null, display, useSignature);
        }
    }
}

IMPORTANT: Don't forget to add the Office/Outlook Library to your project.

Using the Code

Now we can see what we can do using this static class.

Send an email to one recipient, without attachments and without signature:

Email.SendEmail(txtEmail.Text, "Subject", "TEST MESSAGE",true,false); 

In this example, the email address is saved in a TextBox. We don't know if it is valid or not. Also the other arguments could be in TextBoxes or other controls.

Send an email with multiple recipients, multiple attachments and with the signature:

Email.SendEmail(new string [] {recipient1,recipient2,recipient3}, 
"Subject", "TEST MESSAGE",new string[] {attacment1,attachment2,attachment3});   

Points of Interest

The only thing that bothers me in this code is that even if I set the display bool to false, the email is shown for a second. I found out that it is the "GetInspector.Active()" line causing this. Besides that, the code works like it should. :D

History

  • 04.05.2014 - Version 1

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here