ReleaseComObject in InspectorActivate

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

ReleaseComObject in InspectorActivate
 
peter.norman




Posts: 8
Joined: 2018-03-10
Hello Add-In-Express Team! I was hoping you could help with a problem that I've been stuck on. My company's Outlook add-in handles the adxOutlookAppEvents_InspectorActivate and ProcessPropertyChange events. InspectorActivate connects the inspector to our ADXOutlookItemEvents class instance, and then we handle ProcessPropertyChange to perform some actions whenever the user adds a new recipient to an email they're composing. See below:


        private void adxOutlookAppEvents_InspectorActivate(object sender, object inspector, string folderName)
        {
            using (Log.VerboseCall())
            {
                try
                {
                    if (canConnect && !mBlockInspectorActivate) // ?
                    {
                        Outlook._Inspector olInsp = (Outlook._Inspector)inspector;
                        object item = olInsp.CurrentItem;

                        if (item is Outlook._MailItem)
                        {
                            Log.Verbose("connecting to item from InspectorActivate");
                            if (mOutlookItemsEventsMail == null)
                                mOutlookItemsEventsMail = new OutlookItemEventsMailItem(this);
                            if (mOutlookItemsEventsMail.IsConnected)
                                mOutlookItemsEventsMail.RemoveConnection();
                            mOutlookItemsEventsMail.ConnectTo(item, true);
                        }
                        //Marshal.ReleaseComObject(item);
                        //item = null;
                    }
                    if (!canConnect)
                        Log.Verbose("canConnect = false");
                }
                catch (Exception ex)
                {
                    Log.Error(ex);
                }
            }
        }


And


        public override void ProcessPropertyChange(string name)
        {
            if (String.Compare(name, "To", true) == 0)
            {
                try
                {
                    if (this.ItemObj is Outlook.MailItem)
                    {
                        // do something
                    }
                }
                catch (Exception ex)
                {
                }
            }
        }


The code worked fine until recently, when one of our customers upgraded to a new version of a third party's add-in. Since the upgrade, Outlook freezes immediately after our application exits InspectorActivate. No exceptions are thrown on our side and we don't have access to the logs for the other add-in, but we suspect that the problem might be caused by the fact that we were not releasing "item" in InspectorActivate and that this interferes with the other add-in (the Marshal.ReleaseComObject(item) line above was added after we made this diagnosis). However, after changing the code to release "item" in InspectorActivate, we get a "COM object that has been separated from its underlying RCW cannot be used" exception when we hit the first reference to "this.ItemObj" in ProcessPropertyChange.

A few questions:
1. Does it seem plausible to you that not releasing "item" is what is causing the problem with the other add-in? (Our diagnosis is still just our best guess at this point, based on the information we have available)
2. Is it expected that releasing "item" would lead to a COM object error in ProcessPropertyChange?
3. Any thoughts on what we could do to get around this problem?

Many thanks!

Peter
Posted 02 Jul, 2018 15:25:31 Top
Andrei Smolin


Add-in Express team


Posts: 18818
Joined: 2006-05-11
Hello Peter,

#1. Well, I can't tell.
#2. In your version of code, yes.
#3. Does the issue persist if you do nothing in ProcessPropertyChange? don't connect to events? don't call olInsp.CurrentItem (and don't connect to events)? Does the issue occur on a new add-in having only the code you provide in this topic?


                if (item is Outlook._MailItem) 
                { 
                    Log.Verbose("connecting to item from InspectorActivate"); 
                    if (mOutlookItemsEventsMail == null) 
                        mOutlookItemsEventsMail = new OutlookItemEventsMailItem(this); 
                    if (mOutlookItemsEventsMail.IsConnected) 
                        mOutlookItemsEventsMail.RemoveConnection(); 
                    mOutlookItemsEventsMail.ConnectTo(item, true); 
                } 
                else
                {
                    Marshal.ReleaseComObject(item); 
                    item = null; 
                }



That is, you only connect to an item's events if the item is Outlook._MailItem.


Andrei Smolin
Add-in Express Team Leader
Posted 04 Jul, 2018 01:44:00 Top
peter.norman




Posts: 8
Joined: 2018-03-10
Thanks for looking into this, Andrei. It seems like there's no obvious magic bullet and we'll just have to do further testing on the customer's system, along the lines you suggest. I appreciate the thoughts.
Posted 04 Jul, 2018 10:16:13 Top
Andrei Smolin


Add-in Express team


Posts: 18818
Joined: 2006-05-11
You are welcome.


Andrei Smolin
Add-in Express Team Leader
Posted 04 Jul, 2018 10:22:41 Top