none
Issues with UI when manipulating emails in Outlook add-in RRS feed

  • Question

  • I've created an add-in to Outlook that overrides the sender account used for sending emails in Outlook. If for instance Outlook is set up with two email accounts, A and B. The addin is supposed to send all mails using account A (user selects sender account through UI).

    The code is quite easy:

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            Globals.ThisAddIn.Application.Inspectors.NewInspector += Inspectors_NewInspector;
        }
    
        void Inspectors_NewInspector(Outlook.Inspector Inspector)
        {
            if (Inspector.CurrentItem is Outlook.MailItem && MailAddin.IsEnabled)
            {
                SetSender(Inspector);
            }
        }
    
        private void SetSender(Outlook.Inspector inspector)
        {
            var mailItem = inspector.CurrentItem as Outlook.MailItem;
            mailItem.Subject += " (override sender was here)";
    
            var account = Globals.ThisAddIn.MailAddin.SelectedAccountAsOfficeComObject;
    
            mailItem.SendUsingAccount = account;
            mailItem.Sender = account.CurrentUser.AddressEntry;
    
            Marshal.FinalReleaseComObject(account);
            Marshal.FinalReleaseComObject(mailItem);
        }

    (MailAddin is just a object that holds information on whether add-in is active or not, and which account to use as sender).

    My problem is very strange. When I hit "New Email" in outlook everything works fine. The from-field is updated with correct value, along with the subject field (which is only set for testing purposes). Afterwards, when the compose window (and mail is either sent or discarded, doesn't matter which) is closed and I once again hit "New Email", my problem is that the from field is not visibly updated in the user interface. The subject field is set with no problems and appears as expected. If I actually send the mail the correct sender account is used, meaning the account I set through code and not the account that is visible from the user interface.

    I've also noticed that if I leave the first window, that has everything set correctly open (or minimized) while clicking "New Email", all subsequent windows will have the "from field" set correctly in the UI.

    Is there anybody that have any experience with this that can guide me on how to fix this or recommend alternative ways to implement this?

    Thursday, April 3, 2014 1:09 PM

All replies

  • Hello,

    First of all, I'd recommend declaring a global variable at the class scope for handling the NewInspector event.

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
       Globals.ThisAddIn.Application.Inspectors.NewInspector += Inspectors_NewInspector;
    }

    You will not get any event notifications after an instance of the Inspectors class is swiped by the garbage collector. So, you need to keep the reference alive and don't allow to swipe it out.

    Also I'd suggest waiting for the first Activate event, don't access item properties in the NewInspector event.

    Finally, I'd recommend releasing *all* underlying COM objects instantly. For example, the CurrentUserproperty returns an instance of the Recipient class which should be released after.  Use System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Outlook object when you have finished using it. Set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. Read more about this in the Systematically Releasing Objects article in MSDN.

    Thursday, April 3, 2014 1:24 PM
  • Thanks for your reply. I've tried implementing your changes. For the startup method:

    private Outlook.Inspectors _inspectors;
    
            private void ThisAddIn_Startup(object sender, System.EventArgs e)
            {
                _inspectors = Globals.ThisAddIn.Application.Inspectors;
               
                _inspectors.NewInspector += Inspectors_NewInspector;
              }

    As for the event handler I tried

    void Inspectors_NewInspector(Outlook.Inspector Inspector)
            {
                ((Outlook.InspectorEvents_10_Event)Inspector).Activate += ThisAddIn_Activate;
                
            }
    
    void ThisAddIn_Activate()
            {
                var inspector = Globals.ThisAddIn.Application.ActiveInspector();
    
                if (inspector.CurrentItem is Outlook.MailItem && MailAddin.IsEnabled)
                {
                    SetSender(inspector);
                }
            }

    The problem here is how do I access the inspector in the Activate event handler. My trial of Application.ActiveInspector() above gives me a null value.

    I've also updated SetSender as you can see below:

    private void SetSender(Outlook.Inspector inspector)
            {
                
                var mailItem = inspector.CurrentItem as Outlook.MailItem;
                mailItem.Subject += " (override sender was here)";
    
                var account = Globals.ThisAddIn.MailAddin.SelectedAccountAsOfficeComObject;
                var currentUser = account.CurrentUser;
    
                mailItem.SendUsingAccount = account;
                mailItem.Sender = currentUser.AddressEntry;
    
                Marshal.ReleaseComObject(account);
                Marshal.ReleaseComObject(mailItem);
                Marshal.ReleaseComObject(currentUser);
    
                account = null;
                mailItem = null;
                currentUser = null;
                
                Marshal.FinalReleaseComObject(inspector);
            }


    Any ideas?

    Thursday, April 3, 2014 2:53 PM
  • As a workaround, you can try to use the GetInspector method of the MailItem class. 

    And I still see that you don't release all underlying COM objects:

    if (inspector.CurrentItem is Outlook.MailItem && MailAddin.IsEnabled)
    

    The CurrentItem property returns an Object representing the current item being displayed in the inspector. It should be released after.

    Thursday, April 3, 2014 4:13 PM
  • In ThisAddIn_Activate I don't have access to the Inspector or the MailItem as far as I know? So how do I get access to the mailitem in SetSender()?
    Thursday, April 3, 2014 4:41 PM
  • Your code should work properly:

    var inspector = Globals.ThisAddIn.Application.ActiveInspector();
    

    Is there any inspector window visible?
    Thursday, April 3, 2014 5:24 PM
  • That line only results in a null value for inspector I'm afraid
    Thursday, April 3, 2014 6:19 PM
  • It looks like you forgot to answer my last question. Is there any visible inspector window?
    Thursday, April 3, 2014 6:26 PM
  • Oh, sorry about that. I have a breakpoint at the "var inspector = ..." line. At this point no other window has appeared in Outlook, only the main window.
    Thursday, April 3, 2014 6:28 PM
  • It looks like we have found the reason why you get null. Did try to handle the Activate event later (when the inspector window is visible)?
    Thursday, April 3, 2014 7:12 PM
  • No I haven't. If I wan't the sender address to be set automatically when a new inspector is opened, what other event or functionality can I tap into?
    Thursday, April 3, 2014 9:28 PM
  • Hi Kristwa,

    Since I don’t know how you define the object “MailAddin”, I made a sample from yours to test.

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            Globals.ThisAddIn.Application.Inspectors.NewInspector += Inspectors_NewInspector;
        }
    
        void Inspectors_NewInspector(Outlook.Inspector Inspector)
        {
            if (Inspector.CurrentItem is Outlook.MailItem)
            {
                SetSender(Inspector);
            }
        }
    
        private void SetSender(Outlook.Inspector inspector)
        {
            var mailItem = inspector.CurrentItem as Outlook.MailItem;
            mailItem.Subject += " (override sender was here)";
    
            var account = Globals.ThisAddIn.Application.Session.Accounts[1];
            mailItem.SendUsingAccount = account;
            mailItem.Sender = account.CurrentUser.AddressEntry;
    
            Marshal.FinalReleaseComObject(account);
            Marshal.FinalReleaseComObject(mailItem);
        }
    

    I haven’t reproduced the issue as you mentioned.

    I suppose the issue is caused by "MailAddin".

    >> My problem is that the from field is not visibly updated in the user interface. <<

    Do you mean the sender is displayed as the last selection?

    Have you tried to debug the object “account” for the second time you open a new email window?

    It would be better if you share how you define “MailAddin”.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Friday, April 4, 2014 10:19 AM
    Moderator
  • Hi, thanks for your reply. I've tried with your sample code and the problem is still the same.

    When I hit "New email" the first time, everything appears as expected in the composer. If the first composer is dismissed and I try once again, it will open as you can see in 2. The From field is not showing the correct sender. If I actually hit the "From"-dropdown it seems like the ZZZ-account is really checked anyways, even if the user interface is not updated to show it.

    If I actually send the mail, it will be sent with the ZZZ-account.

    Friday, April 4, 2014 11:01 AM
  • Hello,

    As a workaround, you can try to intercept the New Mail button in Outlook and then in the event handler you can cancel creating of a new item. Instead, you may create a new mail item in the code, set the correct account and then just call the Display method.  

    You can read more about repurposing Ribbon controls in the Temporarily Repurpose Commands on the Office Fluent Ribbon article in MSDN.

    Friday, April 4, 2014 11:38 AM
  • How will that interfere with any other add-ins in Outlook? There are a few other third party addons that are running and I cannot deliver something that interfers with these. 
    Friday, April 4, 2014 12:34 PM
  • The functionality shouldn't affect other add-ins. The mail item will be created anyway. It doesn't matter whether an item is created by your code or not. All events will be fired whether you are doing something programmatically or manually.

    However, please remember that if multiple add-ins are trying to repurpose the same UI control the last add-in wins.

    Friday, April 4, 2014 12:50 PM