{"id":868,"date":"2008-10-20T15:42:21","date_gmt":"2008-10-20T14:42:21","guid":{"rendered":"http:\/\/www.craigmurphy.com\/blog\/?p=868"},"modified":"2008-10-20T15:42:21","modified_gmt":"2008-10-20T14:42:21","slug":"implementing-getemailaddressfromexchange-in-c","status":"publish","type":"post","link":"http:\/\/www.craigmurphy.com\/blog\/?p=868","title":{"rendered":"Implementing GetEmailAddressFromExchange in C#"},"content":{"rendered":"<p>As developers we often find ourselves writing small one off applications to perform a specific &#8220;here and now&#8221; requirement.  The task was to produce a list of e-mail addresses from a Microsoft Outlook folder.  I&#8217;m reasonably happy with my understanding of the Microsoft Outlook object model, well, happy enough that I&#8217;ve managed to get it to do what I need it to do.  I am by no means an expert, however since I&#8217;ve been making reasonable progress with my &#8220;duplicate e-mail remover&#8221; application, I figured that iterating over an Outlook folder extracting the e-mail address on they way couldn&#8217;t be too hard.<\/p>\n<p>Indeed, for SMTP e-mail addresses, it&#8217;s fairly straightforward &#8211; a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa210946(office.11).aspx\">mail message<\/a> in Outlook has a <strong>SenderEmailAddress<\/strong> property that holds the e-mail address in the format <strong>name@domain.com<\/strong>.  <\/p>\n<p>In a corporate environment you may find X400 formatted addresses similar to this one: <\/p>\n<p>\/O=<YOUR COMPANY NAME>\/OU=GLOBAL\/CN=RECIPIENTS\/CN=FBUTCHER76409312  <\/p>\n<p>The aforementioned SenderEmailAddress is also used to store this address, so if you were expecting an SMTP address, too bad!  <\/p>\n<p>However, mail messages also have a string property <strong>SenderEmailType<\/strong> which returns EX for mail items that use Exchange Server addressing.  Here&#8217;s how you might use it:<\/p>\n<pre name=\"code\" class=\"csharp\">\r\n               \/\/ Catch e-mails sitting on an Exchange Server...\r\n                            if (oMsg.SenderEmailType == \"EX\")\r\n                            {                                \r\n                                display = GetEmailAddressFromExchange(oMsg.SenderName);\r\n                            }\r\n                            else\r\n                                \/\/ Otherwise, assume SMTP addresses\r\n                                display = string.Format(\"{0}\", oMsg.SenderEmailAddress);\r\n<\/pre>\n<p>The eagle-eyed reader will have noticed the call to <strong>GetEmailAddressFromExchange.<\/strong>   I really wanted an SMTP address for all the mail items in the folder(s) in question.  A little bit of searching revealed <a href=\"http:\/\/anoriginalidea.wordpress.com\/2008\/01\/11\/getting-the-smtp-email-address-of-an-exchange-sender-of-a-mailitem-from-outlook-in-vbnet-vsto\/\">this well-written article<\/a> by Julian Biddle at <a href=\"http:\/\/anoriginalidea.wordpress.com\/\">An Original Idea<\/a>.<\/p>\n<p>Julian&#8217;s article explained how to get an e-mail address from an Exchange Server address using Visual Basic in .NET.  I prefer to use C#, so set about converting Julian&#8217;s code (which was known to work).  There are other flavours of this code floating on the Internet, this one works for me, <a href=\"http:\/\/en.wikipedia.org\/wiki\/Your_mileage_may_vary\">your mileage may vary<\/a>.<\/p>\n<p>The entire application can be downloaded <a href=\"http:\/\/www.craigmurphy.com\/blog\/wp-content\/uploads\/2008\/10\/OutlookEmailExtractor.zip\">here<\/a>.  This little application is crude, but it solved a problem for me at the time of writing.  It demonstrates how to iterate over Microsoft Outlook folders (not just the Inbox) building a treeview on the way.  It also demonstrates how to save the contents of a ListView control to a CSV file.  <\/p>\n<pre name=\"code\" class=\"csharp\">\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.ComponentModel;\r\nusing System.Data;\r\nusing System.Drawing;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Windows.Forms;\r\nusing Microsoft.Office.Interop.Outlook;\r\nusing System.Runtime.InteropServices;\r\nusing System.IO;\r\n\r\nnamespace OutlookEmailAddressExtractor\r\n{\r\n    public partial class frmExtractEmailAddresses : Form\r\n    {\r\n        public frmExtractEmailAddresses()\r\n        {\r\n            InitializeComponent();\r\n        }\r\n\r\n        const int S_OK = 0;\r\n\r\n        [DllImport(\"MAPI32.DLL\", CharSet = CharSet.Ansi, EntryPoint = \"HrGetOneProp@12\")]\r\n        private static extern void HrGetOneProp(IntPtr pmp, uint ulPropTag, out IntPtr ppProp);\r\n\r\n        [DllImport(\"MAPI32.DLL\", CharSet = CharSet.Ansi, EntryPoint = \"HrSetOneProp@8\")]\r\n        private static extern void HrSetOneProp(IntPtr pmp, IntPtr pprop);\r\n\r\n        [DllImport(\"MAPI32.DLL\", CharSet = CharSet.Ansi, EntryPoint = \"MAPIFreeBuffer@4\")]\r\n        private static extern void MAPIFreeBuffer(IntPtr lpBuffer);\r\n\r\n        [DllImport(\"MAPI32.DLL\", CharSet = CharSet.Ansi)]\r\n        private static extern int MAPIInitialize(IntPtr lpMapiInit);\r\n\r\n        [DllImport(\"MAPI32.DLL\", CharSet = CharSet.Ansi)]\r\n        private static extern void MAPIUninitialize();\r\n\r\n        const string IID_IMAPIProp = \"00020303-0000-0000-C000-000000000046\";\r\n        const uint PR_SMTP_ADDRESS = 972947486;\r\n\r\n        struct SPropValue\r\n        {\r\n            public uint ulPropTag;\r\n            public uint dwAlignedPad;\r\n            public long Value;\r\n        }\r\n\r\n        Microsoft.Office.Interop.Outlook.Application oApp;\r\n        NameSpace oNS;\r\n\r\n\r\n        private string GetEmailAddressFromExchange(string emailName)\r\n        {\r\n            MailItem loDummyMsg = (MailItem)oApp.CreateItem(OlItemType.olMailItem);\r\n            Recipient loAddress = loDummyMsg.Recipients.Add(emailName);\r\n            loAddress.Resolve();\r\n            string SMTPAddress = GetMAPIProperty(loAddress.AddressEntry.MAPIOBJECT, PR_SMTP_ADDRESS);\r\n\r\n            return SMTPAddress;\r\n        }\r\n\r\n\r\n        private string GetMAPIProperty(object oMAPIObject, uint uiPropertyTag)\r\n        {\r\n            if (oMAPIObject == null)\r\n            {\r\n                return \"\";\r\n            }\r\n\r\n            string sProperty = \"\";\r\n            IntPtr pPropValue = IntPtr.Zero;\r\n\r\n            IntPtr IUnknown = IntPtr.Zero;\r\n            IntPtr IMAPIProperty = IntPtr.Zero;\r\n\r\n            try\r\n            {\r\n                MAPIInitialize(IntPtr.Zero);\r\n\r\n                IUnknown = Marshal.GetIUnknownForObject(oMAPIObject);\r\n\r\n                Guid guidMAPIProp = new Guid(IID_IMAPIProp);\r\n\r\n                if (Marshal.QueryInterface(IUnknown, ref guidMAPIProp, out IMAPIProperty) != S_OK)\r\n                {\r\n                    return \"\";\r\n                }\r\n\r\n                try\r\n                {\r\n                    HrGetOneProp(IMAPIProperty, uiPropertyTag, out pPropValue);\r\n\r\n                    if (pPropValue == IntPtr.Zero)\r\n                    {\r\n                        return \"\";\r\n                    }\r\n\r\n                    SPropValue propValue = (SPropValue)Marshal.PtrToStructure(pPropValue, typeof(SPropValue));\r\n\r\n                    sProperty = Marshal.PtrToStringAnsi(new IntPtr(propValue.Value));\r\n                }\r\n                catch (System.Exception ex)\r\n                {\r\n                    throw ex;\r\n                }\r\n            }\r\n            finally\r\n            {\r\n                if (pPropValue != IntPtr.Zero)\r\n                {\r\n                    MAPIFreeBuffer(pPropValue);\r\n                }\r\n\r\n                if (IMAPIProperty != IntPtr.Zero)\r\n                {\r\n                    Marshal.Release(IMAPIProperty);\r\n                }\r\n\r\n                if (IUnknown != IntPtr.Zero)\r\n                {\r\n                    Marshal.Release(IUnknown);\r\n                }\r\n\r\n                MAPIUninitialize();\r\n            }\r\n\r\n            return sProperty;\r\n        }\r\n\r\n        \r\n\r\n        void _PopulateFolderList(MAPIFolder oFolder, TreeNode node)\r\n        {\r\n            foreach (MAPIFolder folder in oFolder.Folders)\r\n            {\r\n                string s =String.Format(\"{0} ({1}) [{2}]\", \r\n                                        folder.Name, \r\n                                        folder.Folders.Count, \r\n                                        folder.Items.Count);\r\n                \r\n                TreeNode thisNode = node.Nodes.Add(s);\r\n\r\n                thisNode.Tag = folder;\r\n\r\n                if (folder.Folders.Count > 0)\r\n                {\r\n                    _PopulateFolderList(folder, thisNode);\r\n                }\r\n            }\r\n        }\r\n\r\n        private void btnGetFolders_Click(object sender, EventArgs e)\r\n        {\r\n            oApp = new Microsoft.Office.Interop.Outlook.Application();\r\n            oNS = oApp.GetNamespace(\"MAPI\");\r\n\r\n            progressBar.Minimum = 0;\r\n            progressBar.Maximum = oNS.Folders.Count;\r\n            progressBar.Value = 0;\r\n\r\n            this.Cursor = Cursors.WaitCursor;\r\n\r\n            foreach (MAPIFolder f in oNS.Folders)\r\n            {\r\n                TreeNode node = tvOutlookFolders.Nodes.Add(f.Name);\r\n\r\n                if (f.Name != \"Public Folders\" && f.Name != \"Internet Calendars\")\r\n                    _PopulateFolderList(f, node);\r\n\r\n                progressBar.Value++;\r\n            }\r\n\r\n            progressBar.Value = 0;\r\n            this.Cursor = Cursors.Arrow;\r\n        }\r\n\r\n\r\n         \r\n\r\n        private void btnGetEmailAddresses_Click(object sender, EventArgs e)\r\n        {\r\n            TreeNode nodeSelected = tvOutlookFolders.SelectedNode;\r\n            MAPIFolder folder = (MAPIFolder)nodeSelected.Tag;\r\n\r\n            this.Cursor = Cursors.WaitCursor;\r\n\r\n            lvEMailInSelectedFolder.Items.Clear();\r\n\r\n            if (folder != null)\r\n            {\r\n                progressBar.Maximum = folder.Items.Count;\r\n                progressBar.Minimum = 0;\r\n                progressBar.Value = 0;\r\n\r\n                string sClassComp = \"IPM.Note\";\r\n\r\n                Items oItems = folder.Items;\r\n\r\n                label1.Text = oItems.Count.ToString();\r\n\r\n                MailItem oMsg = (MailItem)oItems.GetFirst();\r\n\r\n                while (oMsg != null)\r\n                {\r\n                    if (oMsg.MessageClass == sClassComp)\r\n                    {\r\n\r\n                        if (oMsg.Body != null)\r\n                        {\r\n                            string display;\r\n\r\n                            \/\/ Catch e-mails sitting on an Exchange Server...\r\n                            if (oMsg.SenderEmailType == \"EX\")\r\n                            {                                \r\n                                display = GetEmailAddressFromExchange(oMsg.SenderName);\r\n                            }\r\n                            else\r\n                                \/\/ Otherwise, assume SMTP addresses\r\n                                display = string.Format(\"{0}\", oMsg.SenderEmailAddress);\r\n\r\n                            bool okToAdd = true;\r\n                                \r\n                            if (cbIgnoreDuplicates.Checked)\r\n                                okToAdd = lvEMailInSelectedFolder.FindItemWithText(display) == null;\r\n\r\n                            if (okToAdd)\r\n                            {\r\n                                ListViewItem item;\r\n                                item = lvEMailInSelectedFolder.Items.Add(display);\r\n\r\n                                item.SubItems.Add(oMsg.SenderName.ToString());\r\n\r\n                                if (oMsg.Subject != null)\r\n                                    item.SubItems.Add(oMsg.Subject.ToString());\r\n                                else\r\n                                    item.SubItems.Add(\" \");\r\n\r\n                                item.SubItems.Add(oMsg.SenderEmailType);\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                    bool exceptionRaised = true;\r\n\r\n                    while (exceptionRaised)\r\n                    {\r\n                        try\r\n                        {\r\n                            oMsg = (MailItem)oItems.GetNext();\r\n                            progressBar.Value++;\r\n                            exceptionRaised = false;\r\n                        }\r\n                        catch\r\n                        {\r\n                            exceptionRaised = true;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                lvEMailInSelectedFolder.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);\r\n\r\n                btnSaveToCSV.Enabled = true;\r\n\r\n                progressBar.Value = 0;\r\n\r\n                this.Cursor = Cursors.Arrow;\r\n            }\r\n        }\r\n\r\n        private void btnSaveToCSV_Click(object sender, EventArgs e)\r\n        {\r\n            StringBuilder listViewContent = new StringBuilder();\r\n\r\n            foreach (ListViewItem item in this.lvEMailInSelectedFolder.Items)\r\n            {\r\n                listViewContent.Append(\"\\\"\");\r\n                listViewContent.Append(item.Text);\r\n                listViewContent.Append(\"\\\"\");\r\n\r\n                listViewContent.Append(\",\");\r\n\r\n                listViewContent.Append(\"\\\"\");\r\n                listViewContent.Append(item.SubItems[1].Text);\r\n                listViewContent.Append(\"\\\"\");\r\n               \r\n                listViewContent.Append(Environment.NewLine);\r\n            }\r\n\r\n            saveFileDialog.FileName = \"e-mail addresses.csv\";\r\n            saveFileDialog.Filter = \"CSV files (*.csv)|*.csv|All files (*.*)|*.*\";\r\n            saveFileDialog.ShowDialog();\r\n\r\n            if (saveFileDialog.FileName != \"\")\r\n            {\r\n                TextWriter tw = new StreamWriter(saveFileDialog.FileName);\r\n\r\n                tw.WriteLine(listViewContent.ToString());\r\n\r\n                tw.Close();\r\n            }\r\n        }\r\n\r\n        private void tvOutlookFolders_AfterSelect(object sender, TreeViewEventArgs e)\r\n        {\r\n            if (tvOutlookFolders.SelectedNode != null)\r\n            {\r\n                btnGetEmailAddresses.Enabled = true;\r\n            }\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>Technorati Tags: <a href=\"http:\/\/technorati.com\/tag\/GetEmailAddressFromExchange\" rel=\"tag\">GetEmailAddressFromExchange<\/a>, <a href=\"http:\/\/technorati.com\/tag\/Julian+Biddle\" rel=\"tag\">Julian Biddle<\/a>, <a href=\"http:\/\/technorati.com\/tag\/An+Original+Idea\" rel=\"tag\">An Original Idea<\/a>, <a href=\"http:\/\/technorati.com\/tag\/Microsoft+Outlook\" rel=\"tag\">Microsoft Outlook<\/a>, <a href=\"http:\/\/technorati.com\/tag\/Outlook\" rel=\"tag\">Outlook<\/a>, <a href=\"http:\/\/technorati.com\/tag\/Microsoft+Exchange+Server\" rel=\"tag\">Microsoft Exchange Server<\/a>, <a href=\"http:\/\/technorati.com\/tag\/Exchange+Server\" rel=\"tag\">Exchange Server<\/a>, <a href=\"http:\/\/technorati.com\/tag\/Exchange\" rel=\"tag\">Exchange<\/a>, <a href=\"http:\/\/technorati.com\/tag\/e-mail+address\" rel=\"tag\">e-mail address<\/a>, <a href=\"http:\/\/technorati.com\/tag\/ListView\" rel=\"tag\">ListView<\/a>, <a href=\"http:\/\/technorati.com\/tag\/Save\" rel=\"tag\">Save<\/a>, <a href=\"http:\/\/technorati.com\/tag\/CSV\" rel=\"tag\">CSV<\/a>, <a href=\"http:\/\/technorati.com\/tag\/SaveToCSV\" rel=\"tag\">SaveToCSV<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>As developers we often find ourselves writing small one off applications to perform a specific &#8220;here and now&#8221; requirement. The task was to produce a list of e-mail addresses from a Microsoft Outlook folder. I&#8217;m reasonably happy with my understanding of the Microsoft Outlook object model, well, happy enough that I&#8217;ve managed to get it &hellip; <a href=\"http:\/\/www.craigmurphy.com\/blog\/?p=868\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Implementing GetEmailAddressFromExchange in C#<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15,3],"tags":[],"class_list":["post-868","post","type-post","status-publish","format-standard","hentry","category-net","category-development"],"_links":{"self":[{"href":"http:\/\/www.craigmurphy.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/868","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.craigmurphy.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.craigmurphy.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.craigmurphy.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.craigmurphy.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=868"}],"version-history":[{"count":0,"href":"http:\/\/www.craigmurphy.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/868\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.craigmurphy.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=868"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.craigmurphy.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=868"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.craigmurphy.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=868"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}