COM object that has been separated from its underlying RCW cannot be used after showing Dialog

Add-in Express™ Support Service
That's what is more important than anything else

COM object that has been separated from its underlying RCW cannot be used after showing Dialog
 
Nick Whymark




Posts: 11
Joined: 2018-01-15
Hi folks,

Hope you're all keeping well in these tricky times!

I have a question which I don't think is related to add-in express but I was hoping you might have some insight. I have an Outlook add-in (using add-in express). My scenario is that I have a ribbon button displayed when composing an email. It shows one or more dialogs to capture some information from the user and then adds some attachments to the email before sending.

I noticed an odd situation where the MailItem COM object is being separated when I show a 2nd dialog, it's fine after showing the first. I've got around it by getting the item again after showing the 2nd dialog, but I'm slightly concerned there may be some memory leak or something. I've created a really simple scenario to confirm:


  Inspector inspector = Globals.OutlookApp.ActiveInspector();
            MailItem mailItem = inspector.CurrentItem as MailItem;

            if (mailItem == null)
            {
                Logger.Error("MailItem is null");
                return;
            }

            try
            {
                Console.WriteLine(mailItem.CreationTime);
                MessageBox.Show("Test1");
                Console.WriteLine(mailItem.CreationTime);
                MessageBox.Show("Test2");
                Console.WriteLine(mailItem.CreationTime); // ERROR THROWN HERE!!!
                MessageBox.Show("Test3");
            }
            catch (Exception ex)
            {
                const string errorMessage = "Error adding documents";
                Logger.Error(ex, errorMessage);
                DialogHelper.DisplayError(errorMessage, "Error", ex);
            }
            finally
            {
                Marshal.ReleaseComObject(mailItem);
            }


Any suggestions as to why this is happening and how I can debug it?

Thanks,
Nick.
Posted 09 Jul, 2020 06:16:49 Top
Andrei Smolin


Add-in Express team


Posts: 17288
Joined: 2006-05-11
Hello Nick,

We are all good, thank you! I trust you are healthy and well too.

Do you handle InspectorActivate, InspectorDectivate, ExplorerActivate, or ExplorerDectivate? If so, can the issue be caused by your code non-prepared to these events being raised while showing/hiding a modal form or message box?

Also, maybe, you use DoEvents?

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 09 Jul, 2020 06:58:55 Top
Nick Whymark




Posts: 11
Joined: 2018-01-15
Hi Andrei,

All good here thanks!

As usual you are spot on. I have the following:

1. I handle Inspector Activate where I hook an ADXOutlookItemEvents object to the mailItem (this is defined as a field in the add-in module).
2. I use this to catch when an email is being forwarded and delete some custom properties.
3. I handle inspector close and call RemoveConnection()

Removing this code makes my issue go away. I'm a bit confused by own code here - as there's only one instance of ADXOutlookItemEvents and I have an odd mix between Activate & Close. I'll take a look!

Thank you!
Posted 09 Jul, 2020 07:30:57 Top
Nick Whymark




Posts: 11
Joined: 2018-01-15
Hi again Andrei!

I noticed that I was setting the second parameter to "true" and then in the InspectorClose event I am calling RemoveConnection. If I set this parameter to "false" then the problem also goes away.

I'm a little confused about how ADXOutlookItemEvents works? As mentioned my reason for using it is to remove some custom properties before the user forwards an email.

I currently have the following:
1. A class called MailItemEvents which inherits from ADXOutlookItemEvents.
2. A single instance of this class in the Addin module:

private MailItemEvents _mailItemEvents;


3. In the AddinStartupComplete I create the object:

_mailItemEvents = new MailItemEvents(this);


4. In the InspectorActivate I hook up the MailItem:

_mailItemEvents.ConnectTo(mailItem, true);


5. And finally in the InspectorClose event I call RemoveConnection:

_mailItemEvents?.RemoveConnection();


When testing my issue the InspectorClose event isn't called - because I haven't closed the inspector yet, but presumably the MailItem is being disposed somewhere. My understanding was that this wouldn't happen until I call RemoveConnection?

If I set the parameter of ConnectTo to false - what do I have to do to clear up? What's the correct way of using ADXOutlookItemEvents to trap the events on an inspector and clean up afterwards?

Thanks again,
Nick.
Posted 09 Jul, 2020 07:51:51 Top
Nick Whymark




Posts: 11
Joined: 2018-01-15
I have worked around the issue by subscribing to the forward event directly on the MailItem in InspectorActivated and unsubscribing in InspectorDeactivated (and InspectorClosed just to be sure).



((ItemEvents_10_Event)mailItem).Forward += MailItemForward;



((ItemEvents_10_Event)mailItem).Forward -= MailItemForward;


This seems to work and my problem has gone away. Fingers crossed the event always fires and no memory leaks. Stupid Outlook! :)
Posted 09 Jul, 2020 10:19:15 Top
Andrei Smolin


Add-in Express team


Posts: 17288
Joined: 2006-05-11
Hello Nick,

Since you connect to that event directly (not via an ADXOutlookItemEvents), make sure you release the COM object that event handler provides as a parameter.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 10 Jul, 2020 05:40:26 Top
Nick Whymark




Posts: 11
Joined: 2018-01-15
Hi Andrei,

Is this good enough, or do you think I need to release the actual object passed ("item")?


        private void MailItemForward(object item, ref bool cancel)
        {
            MailItem mailItem = item as MailItem;
            try
            {
                mailItem?.DeleteAllProperties();
            }
            finally
            {
                Marshal.ReleaseComObject(mailItem);
            }
        }


Thanks again,
Nick.
Posted 10 Jul, 2020 05:47:41 Top
Andrei Smolin


Add-in Express team


Posts: 17288
Joined: 2006-05-11
This is okay. It requires however that you connect to that event on MailItems only.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 10 Jul, 2020 06:42:14 Top