Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Outlook Address Collector

4.00/5 (1 vote)
15 Jul 2011CPOL3 min read 28.2K   804  
Extracts recipients from an email using Outlook

Introduction

This application extracts recipient email addresses from email letters, using Outlook. If you use Outlook (i.e., in a Windows domain), TO and CC fields will show names or email addresses in place of names. Sometimes very useful to collect all email address from letters. Application works with Office2003, never tested with newer versions.

What Problem Does this Solution Solve?

A few weeks ago, I wanted to make a mailgroup by a well-known mailgroup provider. The reason was that we corresponded each other, approx with 30 users. Sometimes the TO field in Outlook was bigger, then message body, and the size of the letter was gratuitously big. So I made a mailgroup, but I had to collect the email addresses. The mailgroup provider uses only email addresses. And I found a big problem. The Outlook sometimes shows the nickname with hyperlink, sometimes shows the email address. Like this:

TO: John Smith;george@anyaddress.com
Of course, You can extract email addresses step by step, but it is a long time (to click, Outlook properties, copy-paste, etc...). And that was the reason that I made this program.

How Does This Help Someone Else? - What is the Edification?

With this simple application, I demonstrate how to use Outlook Interop package, how to reach mail items isn Outlook via this provider, then I show how to iterate on mail items, and how to get attachments. The recipients in Outlook in an Active Directory environment can be simple contacts or domain users. The recipient item contains email address with contacts, but the legacyexchangedn LDAP field with domain users. After all, I show a simple method, how to "translate" the lagacyexchangedn field to an email address by the help of a simple LDAP query. Last but not least, the application will recognize the logged in domain, with the help of a simple WMI query.

Keywords

  • Reach emails in Outlook using Microsoft Office Interop package
  • Get attachments, and recipient items
  • Using LDAP query
  • Using WMI query

Using the Code

First task to solve, how to get email objects from Outlook Inbox. This is an array of MailItems, and we have to extract its properties. Use this to reach default inbox:

C#
//attach Outlook application to myApp object
Microsoft.Office.Interop.Outlook.Application myApp = 
  new Microsoft.Office.Interop.Outlook.ApplicationClass();
//get mapi Namespace
Microsoft.Office.Interop.Outlook.NameSpace mapiNameSpace = myApp.GetNamespace("MAPI");
//Last to reach the default mailbox
Microsoft.Office.Interop.Outlook.MAPIFolder myinbox = 
  mapiNameSpace.GetDefaultFolder(Microsoft.Office.Interop.
                Outlook.OlDefaultFolders.olFolderInbox);

Then get one MailItem, and get its properties. Recipients is a Collection. Use index to select one email item from the myinbox collection.

C#
// Gets email properties
// Get the mailitem's body
richTextBox1.Text = 
    ((Microsoft.Office.Interop.Outlook.MailItem)myInbox.Items[index]).Body;
// Get the mailitem's sender name
textBox3.Text = 
    ((Microsoft.Office.Interop.Outlook.MailItem)myInbox.Items[index]).SenderName;
// Get the mailitem's sender email address 
sendermail = 
    ((Microsoft.Office.Interop.Outlook.MailItem)myInbox.Items[index]).SenderEmailAddress;
// Get all recipients
Microsoft.Office.Interop.Outlook.Recipients recipients = 
  ((Microsoft.Office.Interop.Outlook.MailItem)myInbox.Items[index]).Recipients;

// Iterate recipient from recipients collection

foreach (Microsoft.Office.Interop.Outlook.Recipient item in recipients)
{
  .....
  textBox7.Text = textBox7.Text + item.Address + Environment.NewLine;
}

The second problem that we are interested in is email addresses. If user is an active directory user, then recipientitem.address will looks like this: /o=organizationg/ou=exchange administrative group /cn=recipients/cn=xxxxxxxxxx.

This is one of user LDAP properties named legacyexchangedn.

So if recipinetitem.address contains "CN=", then have to get email address from LDAP server. If we are logged into a domain, the ldapuser, and ldapserver fields can be empty. This is a basic and simple LDAP query. You will meet like this in many-many pages.

C#
private static string getLDAPvalue(string ldapserver, string 
        legacyexchangedn, string ldapuser, string ldappasword)
{    
    //default LDAP path is the root of LDAP tree 
    string strLDAPPath = "";
    string x = "";
    // The result of the LDAP search will be a Directory Entry
    DirectoryEntry objSearchRoot;
    try
    {
        //Using the LDAP protocol. Set the default path to the root. 
        //The LDAP server is one of domain controllers,
        //but better using the fullname of Windows domain.
        //i.e. ldapserver = windowsdomainname.organization.any
        strLDAPPath = "LDAP://" + ldapserver;
        
        //If You are logged into a Windows domain,
        //the LDAP user, and password can be empty. 
        //Windows will use the default logged in user account.
        if (ldapuser == "")
        {
            objSearchRoot = new DirectoryEntry(strLDAPPath);
        }
        else
        {
            //When You not logged into a domain
            objSearchRoot = new DirectoryEntry(strLDAPPath, ldapuser, 
              ldappasword, AuthenticationTypes.ReadonlyServer);
        }

        //First create a directorysearcher object
        DirectorySearcher objDirectorySearcher = new DirectorySearcher(objSearchRoot);
        // Use filter for legacyexchangedn in this example.
        //When You wants to filter for username then use this:
        // objDirectorySearcher.Filter = 
        //  "(&(objectClass=person)(samaccountname=" + username + "))
        objDirectorySearcher.Filter = 
          "(&(objectClass=person)(legacyexchangedn=" + legacyexchangedn + "))";
        //We want to get the email =>in LDAP this is the mail property.
        objDirectorySearcher.PropertiesToLoad.Add("mail");


        SearchResult objSearchResult;
        //We will get only one result, because the legacyexchangedn
        //is unique. If You filter for field has many results
        //You have to use objDirectorySearcher.FindAll();
        
        objSearchResult = objDirectorySearcher.FindOne();
        
        //If we have valid result... This is not necessary.
        //If recipient item contains legacyexchangedn field, then impossible
        //the empty  objSearchResult object.
        
        if (!(objSearchResult == null))
        {
            ResultPropertyValueCollection objValueCollection;
            objValueCollection = objSearchResult.Properties["mail"];
            
            //It is not necessary as well.. The objSearchResult
            //has only one "mail" property
            foreach (object objPropertyValue in objValueCollection)
            {
                x = x + objPropertyValue.ToString();
            }
        }
        else
        {
            x = "No hits";
        }
        
        //Dispose, and close LDAP query
        objDirectorySearcher.CacheResults = false;
        objDirectorySearcher.Dispose();
    }
    //When something is wrong. The common problem,
    //when LDAP server is unreachable, in time of query.
    catch (Exception ex)
    {
        x = "";
        MessageBox.Show(ex.Message);
    }
    return x;
}

And last, this is a simple query from WMI to ask default domain. I found this code snippet somewhere many years ago.

C#
private string getdomain()
{
    string domain = "";

    //to make the Query object
    SelectQuery query = new SelectQuery("Win32_ComputerSystem");
    //Make the searcher object
    ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);

    //To get the name of the logged in domain.
    foreach (ManagementObject mo in searcher.Get())
    {
        if ((bool)mo["partofdomain"] == true)
            domain = String.Format("{0}", mo["domain"]);
    }

    return domain;
}

Full Code

C#
using System;
using System.Windows.Forms;
using System.IO;
using System.DirectoryServices;
using System.Management;

namespace OutlookAddressCollector
{
    public partial class Form1 : Form
    {
        //global variables NOT ELEGANT!!!!!!
        Microsoft.Office.Interop.Outlook.Application myApp ;
        Microsoft.Office.Interop.Outlook.NameSpace mapiNameSpace;
        Microsoft.Office.Interop.Outlook.MAPIFolder myInbox;
        int st;
            
        public Form1()
        {
            InitializeComponent();
        }

        // Gets users email address, when recipient
        // is a member of an Active Directory (i.e. in a company)
        private static string getLDAPvalue(string ldapserver, 
          string legacyexchangedn, string ldapuser, string ldappasword)
        {
            string strLDAPPath = "";
            string x = "";
            DirectoryEntry objSearchRoot;
            try
            {
                strLDAPPath = "LDAP://" + ldapserver;

                if (ldapuser == "")
                {
                    objSearchRoot = new DirectoryEntry(strLDAPPath);
                }
                else
                {
                    objSearchRoot = new DirectoryEntry(strLDAPPath, ldapuser, 
                        ldappasword, AuthenticationTypes.ReadonlyServer);
                }

                DirectorySearcher objDirectorySearcher = 
				new DirectorySearcher(objSearchRoot);
                objDirectorySearcher.Filter = 
                  "(&(objectClass=person)(legacyexchangedn=" + 
                  legacyexchangedn + "))";
                objDirectorySearcher.PropertiesToLoad.Add("mail");

                SearchResult objSearchResult;
                objSearchResult = objDirectorySearcher.FindOne();
                if (!(objSearchResult == null))
                {
                    ResultPropertyValueCollection objValueCollection;
                    objValueCollection = objSearchResult.Properties["mail"];

                    foreach (object objPropertyValue in objValueCollection)
                    {
                        x = x + objPropertyValue.ToString();
                    }
                }
                else
                {
                    x = "No hits";
                }
                objDirectorySearcher.CacheResults = false;
                objDirectorySearcher.Dispose();
            }
            catch (Exception ex)
            {
                x = "";
                MessageBox.Show(ex.Message);
            }
            return x;
        }

        //Refresh datagrid
        private void Refresh(int start)
        {
            try
            {
                if (myInbox.Items.Count == 0)
                {
                    throw new System.Exception("There are no emails in your Inbox.");
                }

                int db = 10;

                if (start - 10 < 0) db = start;

                if (start > myInbox.Items.Count) start = myInbox.Items.Count;

                dataGridView1.Rows.Clear();

                int x = 0;

                for (int i = start; i > start - db; i--)
                {


                    x = dataGridView1.Rows.Add();

                    dataGridView1.Rows[x].Cells[0].Value = i.ToString();
                    dataGridView1.Rows[x].Cells[1].Value = 
                      ((Microsoft.Office.Interop.Outlook.MailItem)
					myInbox.Items[i]).SenderName;
                    dataGridView1.Rows[x].Cells[2].Value = 
                      ((Microsoft.Office.Interop.Outlook.MailItem)
					myInbox.Items[i]).Subject;
                    dataGridView1.Rows[x].Cells[3].Value = 
                      String.Format("{0:yyyy.MM.dd HH:mm:ss}", 
                      ((Microsoft.Office.Interop.Outlook.MailItem)
					myInbox.Items[i]).ReceivedTime);

                    x++;
                }
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Refresh(st);
        }

        // Gets computers domain
        private string getdomain()
        {
            string domain = "";

            SelectQuery query = new SelectQuery("Win32_ComputerSystem");
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);

            foreach (ManagementObject mo in searcher.Get())
            {
                if ((bool)mo["partofdomain"] == true)
                    domain = String.Format("{0}", mo["domain"]);
            }

            return domain;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
          
            textBox2.Text = getdomain();
            myApp = new Microsoft.Office.Interop.Outlook.ApplicationClass();
            mapiNameSpace = myApp.GetNamespace("MAPI");
            myInbox = mapiNameSpace.GetDefaultFolder(
              Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
            st = myInbox.Items.Count;
            Refresh(st);
            dataGridView1_CellClick(sender, null);
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message);
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            st = st - 10;
            if (st < 10) st = 10;
            Refresh(st);
            dataGridView1_CellClick(sender, null);
        }

        public void button4_Click(object sender, EventArgs e)
        {
            st = st + 10;
            if (st > myInbox.Items.Count) st = myInbox.Items.Count;
            Refresh(st);
            dataGridView1_CellClick(sender, null);
        }

        private void button5_Click(object sender, EventArgs e)
        {
            st = myInbox.Items.Count;
            Refresh(st);
            dataGridView1_CellClick(sender, null);
        }

        private void button6_Click(object sender, EventArgs e)
        {
            st = 10;
            Refresh(st);
            dataGridView1_CellClick(sender, null);
        }

        //Saves attachments
        private void button1_Click(object sender, EventArgs e)
        {
            int rownum = dataGridView1.CurrentCell.RowIndex;
            int index = Convert.ToInt32(dataGridView1.Rows[rownum].Cells[0].Value);

            try
            {
                if (((Microsoft.Office.Interop.Outlook.MailItem)
			myInbox.Items[1]).Attachments.Count == 0)
                {
                    throw new System.Exception("There aren't any attachment");

                }
                string foldername = "";
                DialogResult result = this.folderBrowserDialog1.ShowDialog();
                if (result == DialogResult.OK)
                {
                    foldername = this.folderBrowserDialog1.SelectedPath;
                }

                if (foldername == "")
                {
                    throw new System.Exception("Folder name is empty");
                }

                foreach (Microsoft.Office.Interop.Outlook.Attachment item in 
                    ((Microsoft.Office.Interop.Outlook.MailItem)
				myInbox.Items[1]).Attachments)
                {

                    string filename = Path.Combine(foldername, item.FileName);

                    item.SaveAsFile(filename);
                }

            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        // When You click on a datagrid cell.
        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {

            int rownum = dataGridView1.CurrentCell.RowIndex;
            int index = Convert.ToInt32(dataGridView1.Rows[rownum].Cells[0].Value);

            string sendermail = "";

            textBox1.Text = ((Microsoft.Office.Interop.Outlook.MailItem)
					myInbox.Items[index]).Subject;


            richTextBox1.Text = ((Microsoft.Office.Interop.Outlook.MailItem)
				myInbox.Items[index]).Body;
            textBox3.Text = ((Microsoft.Office.Interop.Outlook.MailItem)
				myInbox.Items[index]).SenderName;
            sendermail = ((Microsoft.Office.Interop.Outlook.MailItem)
				myInbox.Items[index]).SenderEmailAddress;

            if (sendermail.Contains("CN="))
            {
                textBox4.Text = getLDAPvalue
			(textBox2.Text, sendermail, textBox8.Text, textBox9.Text);
            }
            else
            {
                textBox4.Text = sendermail;
            }

            textBox5.Text = ((Microsoft.Office.Interop.Outlook.MailItem)
				myInbox.Items[index]).To;
            textBox6.Text = ((Microsoft.Office.Interop.Outlook.MailItem)
				myInbox.Items[index]).CC;
            Microsoft.Office.Interop.Outlook.Recipients recipients = 
              ((Microsoft.Office.Interop.Outlook.MailItem)
				myInbox.Items[index]).Recipients;

            textBox7.Text = "";
            foreach (Microsoft.Office.Interop.Outlook.Recipient item in recipients)
            {
                if (item.Address.Contains("CN="))
                {
                    textBox7.Text = textBox7.Text +getLDAPvalue(textBox2.Text, 
                       item.Address, textBox8.Text, textBox9.Text) + Environment.NewLine;
                }
                else
                {
                    textBox7.Text = textBox7.Text + item.Address + Environment.NewLine;
                }
            }
        }
    }
}

History

  • Version 1.0

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)