none
Outlook couldn't recognize recipients in compose (mailItem.To) when button clicked. RRS feed

  • Question

  • I've wrote a program that should get Recipients email when button clicked. It works when I have used mailItem.Save() but this copy recipients and save it to draft folder which I don't want to happen.

    Is there any way that I can call the functionality of "Check Names" ? or  What should I do to get all recipients instead of using mailItem.Save() ?

    Process: Enter recipients email address to the "To field"

                  Click the button to get recipients email.


     //CC account manager when this button is clicked
            private void uxCcManager_Click(object sender, RibbonControlEventArgs e)
            {
                //check if user is authorized to use this feature
                if (!CheckAuthorization())
                {
                    return; // Authentication failed do not proceed any further
                }
                //save mail items entered in fields else they will get overidden by space

                mailItem.Save();

                mailItem.Recipients.ResolveAll();//check recepent name
                if (mailItem != null)
                {
                    //check if EntryID (unique id passed as a parameter of the event) of the currentItem not null. 
                    //the entry id changes when an item is moved from folder to folder(drafts->outbox->Sent Items).
                    if (mailItem.EntryID != null)
                    {
                        if (mailItem.To == null)
                        {
                            MessageBox.Show("Please, enter the email address that you're sending email to!");
                        }
                        else if (mailItem.To != null)
                        {
                            //get individual emails from mailItem.To for the purpose of getting indivdual account manager
                            if (!IndividualRecipent(mailItem.Recipients))
                            {
                                MessageBox.Show("Cannot identify one or more emails, please check names and try again.");
                            }
                        }
                    }
                }
            }

    Thursday, August 23, 2018 6:05 PM

All replies

  • Do not use the To property (as well as CC and BCC) - they are only updated by the store based on the recipient table when the message is saved. Worse than that, you are only checking for the To recipients, but it is perfectly legal to send to only CC or BCC recipients. And worse yet, To/CC/BCC properties generally only contain display names, but not the email addresses.

    Use MailItem.Recipients collection, loop through it, and for each Recipient object, check the Address and Name properties.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Thursday, August 23, 2018 6:48 PM
  • Thank you for your reply Dmitry!

    Do you know any library that can replace mailItem.Save()? or that "Check Names" before sent functionality.

    Thursday, August 23, 2018 8:53 PM
  • You don't need Save if you are using the Recipients collection. Have you tried that?

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Thursday, August 23, 2018 10:09 PM
  • I've tried that and it didn't work.
    Friday, August 24, 2018 1:02 PM
  • This is Abraham's Co-worker here - Here's an alternate code approach using recipients only...   Cnt is 0 if the names in the new email being composed are not resolved before the button is clicked.

    using Microsoft.Office.Tools.Ribbon;
    using Outlook = Microsoft.Office.Interop.Outlook;
    namespace AddIn1
    {
        public partial class Ribbon1
        {
            private Outlook.Application application;
            private Outlook.Inspector inspector;
            private Outlook.MailItem mailItem;
            private void Ribbon1_Load(object sender, RibbonUIEventArgs e)
            {
                button1.Visible = (this.RibbonId == "Microsoft.Outlook.Mail.Compose");
            }


            private void button1_Click(object sender, RibbonControlEventArgs e)
            {
                application = (application ?? Globals.ThisAddIn.Application);
                inspector = (inspector ?? application.ActiveInspector());
                mailItem = (mailItem ?? inspector.CurrentItem as Outlook.MailItem);

                //check if user is authorized to use this feature
                if (!CheckAuthorization())
                {
                    return; // Authentication failed do not proceed any further
                }

                //mailItem.Save();
                int Cnt = 0;
                foreach (Outlook.Recipient r in mailItem.Recipients)
                {
                    r.Resolve();
                    if (r.Type == (int)Outlook.OlMailRecipientType.olTo) //checking only recipents from "To" field
                    {
                        Cnt += 1;
                    }
                }
                if (Cnt == 0)
                {
                    System.Windows.Forms.MessageBox.Show("Please, enter the email address that you're sending email to.");
                    return;
                }
                //attempt to resolve the emails before we proceed further
                if (!mailItem.Recipients.ResolveAll())
                {
                    System.Windows.Forms.MessageBox.Show("Cannot identify one or more emails, please check names and try again.");
                    return;
                }
                //loop through all recipients in "to" field and find account managers and add them to the "cc" field
                LoopThroughToEmailsAndAddAccountManagersToCC(mailItem.Recipients);

            }
        }
    }

    Problem is without the mailItem.Save(); the unresolved emails in the mailItem (to, cc and bcc) do not exist in the recipients collection or mailitem.to unless the users have clicked the "check names" or the autosave has kicked in (or manual save done) before the button is clicked, none of these are events that we can expect to occur before the button1_click is run. 

    If we use the mailItem.Save() in the button1_click event, the item is saved to the drafts folder.  Then all the code past that point works good.  BUT when user closes outlook there will be a popup message asking "Want to save your changes?" during the closing of outlook for every time that the button1_click has fired the mailItem.Save() on an unsaved mailitem.  Seems almost as if the mailitem.save is creating a new unsaved mailitem in the drafts folder or the reference to the unsaved mailitem is lost and hangs around undisposed when the save() is run on an unsaved mailitem. 

    Seems that we are missing something here. 

    Thanks,

    Tracie


    Friday, August 24, 2018 1:36 PM
  • Outlook does not update any of its object (be that Recipients or Subject) until the focus is moved away from that control.

    Does it work if you click away from the To edit body to the message body or subject before running that code?


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Friday, August 24, 2018 3:23 PM
  • moving the focus from "to field" to another field "CC", "Subject" or "Body" and then clicking the button before the names are auto-resolved does nothing.

    but if you wait ~ 2 to  5 seconds for the "auto resolve" to kick in then the code works. 

    Edit: We can't count on users not adding last minute emails to the "to field" before clicking the button. 


    Friday, August 24, 2018 4:12 PM
  • Hmmm... This is new. I can reproduce this behavior with the following script (I ran it from OutlookSpy). The recipients do not need to be resolved (I typed a log string of junk characters), but it does take a few seconds for OOM to pick them up.

    Are you using Outlook 2016? It did not work that way before, so you might want to file a support case with Microsoft if you want to have this fixed.

    set item = Application.ActiveInspector.CurrentItem
    MsgBox item.Recipients.Count


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Friday, August 24, 2018 4:21 PM
  • Thank you for your input.  Will submit a ticket to Microsoft on this issue. 
    Monday, August 27, 2018 11:00 AM