65.9K
CodeProject 正在变化。 阅读更多。
Home

Outlook 地址收集器

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (1投票)

2011年7月15日

CPOL

3分钟阅读

viewsIcon

28411

downloadIcon

817

从 Outlook 提取电子邮件收件人

引言

这个应用程序使用 Outlook 提取电子邮件中的收件人电子邮件地址。 如果您使用 Outlook(例如,在 Windows 域中),TO 和 CC 字段将显示名称或电子邮件地址,而不是名称。 有时,收集信件中的所有电子邮件地址非常有用。 该应用程序适用于 Office2003,未在较新版本上测试过。

此解决方案解决了什么问题?

几周前,我想通过一个知名的邮件群组提供商创建一个邮件群组。 原因是我们大约与 30 个用户互相通信。 有时 Outlook 中的 TO 字段比消息体大,并且信件的大小不必要地很大。 所以我创建了一个邮件群组,但我必须收集电子邮件地址。 邮件群组提供商仅使用电子邮件地址。 我发现了一个大问题。 Outlook 有时显示带有超链接的昵称,有时显示电子邮件地址。 就像这样

收件人:John Smith; george@anyaddress.com
当然,您可以逐步提取电子邮件地址,但这需要很长时间(单击、Outlook 属性、复制-粘贴等)。 这就是我编写这个程序的原因。

这如何帮助其他人? - 有什么启发?

通过这个简单的应用程序,我演示了如何使用 Outlook Interop 包,如何通过此提供程序访问 Outlook 中的邮件项目,然后我展示了如何迭代邮件项目以及如何获取附件。 在 Active Directory 环境中,Outlook 中的收件人可以是简单的联系人或域用户。 收件人项目包含带有联系人的电子邮件地址,但包含域用户的 legacyexchangedn LDAP 字段。 最后,我展示了一个简单的方法,如何通过简单的 LDAP 查询将 lagacyexchangedn 字段“转换”为电子邮件地址。 最后但并非最不重要的一点是,该应用程序将通过简单的 WMI 查询识别登录的域。

关键词

  • 使用 Microsoft Office Interop 包在 Outlook 中获取电子邮件
  • 获取附件和收件人项目
  • 使用 LDAP 查询
  • 使用 WMI 查询

Using the Code

首先要解决的任务是如何从 Outlook 收件箱获取电子邮件对象。 这是一组 MailItems,我们必须提取其属性。 使用此方法访问默认收件箱

//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);

然后获取一个 MailItem 并获取其属性。 收件人是一个集合。 使用索引从 myinbox 集合中选择一个电子邮件项目。

// 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;
}

我们感兴趣的第二个问题是电子邮件地址。 如果用户是 Active Directory 用户,那么 recipientitem.address 将如下所示:/o=organizationg/ou=exchange administrative group /cn=recipients/cn=xxxxxxxxxx。

这是用户 LDAP 属性之一,名为 legacyexchangedn

因此,如果 recipinetitem.address 包含“CN=”,那么必须从 LDAP 服务器获取电子邮件地址。 如果我们已登录到域,则 ldapuserldapserver 字段可以为空。 这是一个基本的简单 LDAP 查询。 您会在很多很多页面上遇到类似的情况。

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;
}

最后,这是从 WMI 获取默认域的简单查询。 我多年前在某个地方找到了这段代码片段。

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;
}

完整代码

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;
                }
            }
        }
    }
}

历史

  • 版本 1.0
© . All rights reserved.