none
Handling Outlook Inspectors RRS feed

  • Question

  • My current code is interfacing with Office 2010 using VSTO and Visual C#.

    I have a C# add-in for Office 2010 where if a user opens a mail item from a specific folder, the NewInspector event is trapped and, using information about that mail item, retrieves a stored mail item from a document manager to be displayed.  In essence, the first mail item is really a link to the stored mail item (a shared file stored somewhere other than Exchange and managed, in part, via SQL code and SQL Server).

    All the code I have works, but the problem I cannot resolve is that Outlook actually fires off two inspectors: one for the first mail item and a second containing the stored mail item (opened with Session.OpenSharedItem).  I have tried to close the first inspector in the NewInspector, Activate, and Open event handlers, but that causes Outlook to hang. 

    BTW: the only choice in the fora was Office 2013 which I have yet to start to tackle.

    Thanks in advance.

    • Moved by Quist ZhangModerator Monday, December 3, 2012 8:48 AM Outlook issue (From:Developing Apps for Office 2013)
    Saturday, December 1, 2012 4:23 AM

Answers

  • I would create a hidden Windows Form with a timer control on it and instantiate the form in the addin startup code. It will be running on the main Outlook thread. In your Activate() handler start the timer and set a variable identifying the Inspector to close. When the timer fires after you leave Activate() you can then safely close the Inspector.
     
    A System.Timers.Timer object can also be used if any calls made from the timer elapsed event are synched to the main Outlook thread. The Outlook object model should never be used from a background thread.

    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "kptools" <=?utf-8?B?a3B0b29scw==?=> wrote in message news:286460f0-b869-42cf-9ccd-63ad926892b8...
    Well, I tried that. New_Inspector now only sets a local variable to be the new inspector passed to the event and subscribes that inspector to the activate event. In activate, i determine if the mail item is a managed one (actual message file is stored somewhere else) or a non-managed one. If non-managed, I basically do little other than subscribe to attachment open events. if managed, i (a) close and null that inspector, (b) close and null the mail item, (c) open a new mail item using OpenSharedItem, (d) reset the inspector local variable using the new mail item GetInspector. And viola! I still have two inspectors open (but the managed file loads into an inspector).

    Ken Slovak MVP - Outlook
    • Marked as answer by kptools Friday, December 7, 2012 11:52 PM
    Thursday, December 6, 2012 2:53 PM
    Moderator

All replies

  • There is no Open() event for the Inspector object, are you using the Open() event for Inspector.CurrentItem?
     
    How are you closing the Inspector, doing so should not hang Outlook. I've used code to close Inspectors many times without causing Outlook to hang.
     
    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "kptools" <=?utf-8?B?a3B0b29scw==?=> wrote in message news:cdf86be4-cb4e-422e-a5c2-db582efb22ff...

    My current code is interfacing with Office 2010 using VSTO and Visual C#.

    I have a C# add-in for Office 2010 where if a user opens a mail item from a specific folder, the NewInspector event is trapped and, using information about that mail item, retrieves a stored mail item from a document manager to be displayed.  In essence, the first mail item is really a link to the stored mail item (a shared file stored somewhere other than Exchange and managed, in part, via SQL code and SQL Server).

    All the code I have works, but the problem I cannot resolve is that Outlook actually fires off two inspectors: one for the first mail item and a second containing the stored mail item (opened with Session.OpenSharedItem).  I have tried to close the first inspector in the NewInspector, Activate, and Open event handlers, but that causes Outlook to hang. 

    BTW: the only choice in the fora was Office 2013 which I have yet to start to tackle.

    Thanks in advance.


    Ken Slovak MVP - Outlook
    Monday, December 3, 2012 2:41 PM
    Moderator
  • Thanks.  I realize that there is no Open() event for the Inspector object; the Open() event I trap is
    for mailitems, as was the Activate (both of which I no longer trap).
    The sequence of the code/logic is basically as follows:
    1.  A user double-clicks a mailitem in an Outlook explorer folder. 
    2.  I trap the NewInspector() event and, if the MailItem is one of interest, attempted to close the Inspector object
    passed NewInspector() as a parameter. 
    3.  As the MailItem is, in reality, a link to an external document, I then retrieve that external document and open it via OpenSharedItem. 
    4.  If successful (and there's other logic at play here), I then display the newly opened MailItem, using MailItem.GetInspector to obtain the new MailItem's Inspector object.
    Closing the originally passed Inspector object in NewInspector() allowed the code to progress through all of the invoked methods; the new MailItem Inspector gets displayed; and Outlook hangs.  I tried to not close the original Inspector item in NewInspector, closing it instead in my downstream logic, but had the same result.
    If I do not attempt to close the original Inspector item at all, the code works but both inspectors are
    displayed.  Thus, I presume that the error has to lie with closing the first Inspector object.
    I will send a more detailed set of (redacted) code later (I am not where I can get to it).
    Thanks for your help.
    ,,, Gary R Maze
    President
    GarLin Co.
    Monday, December 3, 2012 5:59 PM
  • either you are trying to close inspector too soon or you display them as modal dialogs
    Monday, December 3, 2012 7:03 PM
  • what does "too soon" mean, in this context?  That is, when is it not too soon to close the Inspector?  As far as displaying them as modal, I do not believe that I am.

    Thanks.

    Monday, December 3, 2012 7:10 PM
  • Do not attempt to close the Inspector before the Inspector's first Activate() event occurs. If you plan to close it subscribe to the Activate() event and in that event call the Inspector's Close() method.

    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "kptools" <=?utf-8?B?a3B0b29scw==?=> wrote in message news:92d7c5f1-7233-4a1f-b8e0-ff7ee8598690...

    what does "too soon" mean, in this context?  That is, when is it not too soon to close the Inspector?  As far as displaying them as modal, I do not believe that I am.

    Thanks.


    Ken Slovak MVP - Outlook
    Monday, December 3, 2012 11:09 PM
    Moderator
  • here's the redacted code:

          m_goOutlook is set to be the current Outlook application; m_goExplorer, m_goMailItem, and m_goInspector are properly declared variables

          public override void setOutlookEventsHandler()

            {
                //============ Set up the event handlers ===============
                try
                {
                    m_goOutlook.NewMail += new Outlook.ApplicationEvents_11_NewMailEventHandler(
                        m_goOutlook_NewMail);
                    m_goOutlook.ItemLoad += new Outlook.ApplicationEvents_11_ItemLoadEventHandler(
                        m_goOutlook_ItemLoad);
                    m_goExplorer.SelectionChange += new Outlook.ExplorerEvents_10_SelectionChangeEventHandler
                        (CurrentExplorer_Event);
                    m_goExplorer.ViewSwitch += new Outlook.ExplorerEvents_10_ViewSwitchEventHandler(
                        m_goExplorer_ViewSwitch);
                    m_goExplorer.FolderSwitch += new Outlook.ExplorerEvents_10_FolderSwitchEventHandler
                        (m_goOutlook_FolderSwitch);
                    m_goExplorer.BeforeItemCopy += new Outlook.ExplorerEvents_10_BeforeItemCopyEventHandler
                        (copyToNataero);
                    m_goExplorer.BeforeItemCut += new Outlook.ExplorerEvents_10_BeforeItemCutEventHandler
                        (cutToNataero);
                    m_goExplorer.BeforeItemPaste += new Outlook.ExplorerEvents_10_BeforeItemPasteEventHandler
                        (moveToNataero);
                    Outlook.Inspectors olInspectors = m_goOutlook.Inspectors;
                    olInspectors.NewInspector += new Outlook.InspectorsEvents_NewInspectorEventHandler(
                        m_goOutlook_NewInspector);
                    m_InspectorWindows = new List<Outlook.Inspector>();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("setOutlookEventsHandler: " + ex.Message);
                }
            }

            private void m_goOutlook_NewInspector(Outlook.Inspector toInspector)
            {
                try
                {
                    ((Outlook.InspectorEvents_10_Event)toInspector).Activate += new Outlook.InspectorEvents_10_ActivateEventHandler(
                        Inspector_Activate);
                    Outlook.MailItem loMailItem = toInspector.CurrentItem
                        as Outlook.MailItem;
                     ....

                     m_goMailItem = toInspector.CurrentItem;
                    m_goMailItem.AttachmentRead +=new Outlook.ItemEvents_10_AttachmentReadEventHandler(
                        m_goMailItem_AttachmentRead);
                    m_goMailItem.BeforeAttachmentPreview += new Outlook.ItemEvents_10_BeforeAttachmentPreviewEventHandler(
                        m_goMailItem_BeforeAttachmentPreview);
                    m_goMailItem.BeforeAttachmentRead +=new Outlook.ItemEvents_10_BeforeAttachmentReadEventHandler(
                        m_goMailItem_BeforeAttachmentRead);
                    if (<condition>)
                    {
                        //
                        //  if we are in a managed folder, open the file
                        //
                        m_loSelectedFolder = m_goExplorer.CurrentFolder;
                        if (isManagedFolder(m_loSelectedFolder.FolderPath.Trim()))
                        {
                            m_goMailItem = null;
                            Object selObject = m_goExplorer.Selection[1];
                            if (selObject is Outlook.MailItem)
                            {
                                //
                                //  m_goMailItem is now the dummy entry
                                //  in the Explorer window
                                //
                                m_goMailItem = (selObject as Outlook.MailItem);
                            }
                        }
                    }
                    //
                    //  if we open (e.g., load) the email
                    //  message succesfully, launch the viewer
                    //
                    if (<condition>)
                    {
                        if (openMailItem(m_liFileId))
                        {
                            m_goMailItem.Display();
                            finishOpen();
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                closeInfo();
            }

           private void finishOpen()
            {
                try
                {
                    if (<conditon>)
                    {
                        //
                        //  open the new inspector for this email
                        //
                        if (m_goMailItem != null)
                        {
                            m_goInspector = m_goMailItem.GetInspector;
                            ((Outlook.InspectorEvents_10_Event)m_goInspector).Close +=
                                new Outlook.InspectorEvents_10_CloseEventHandler(m_goInspector_Close);
                            m_goInspector.AttachmentSelectionChange += new Outlook.InspectorEvents_10_AttachmentSelectionChangeEventHandler(
                                m_goInspector_AttachmentSelectionChange);
                            ((Outlook.InspectorEvents_10_Event)m_goInspector).Activate += new Outlook.InspectorEvents_10_ActivateEventHandler(
                                Inspector_Activate);

                            //
                            m_goMailItem.AttachmentRead += new Outlook.ItemEvents_10_AttachmentReadEventHandler(
                                m_goMailItem_AttachmentRead);
                            m_goMailItem.BeforeAttachmentPreview += new Outlook.ItemEvents_10_BeforeAttachmentPreviewEventHandler(
                                m_goMailItem_BeforeAttachmentPreview);
                            m_goMailItem.BeforeAttachmentRead += new Outlook.ItemEvents_10_BeforeAttachmentReadEventHandler(
                                m_goMailItem_BeforeAttachmentRead);
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                closeInfo();
            }

            private void Inspector_Activate()
            {
                try
                {
                    String lsBody = String.Empty;
                    if (m_goOutlook.ActiveInspector() == null)
                    {
                        lsBody = ((Outlook.MailItem)m_goInspector.CurrentItem).Body.Trim();
                    }
                    else
                    {
                        lsBody = ((Outlook.MailItem)m_goOutlook.ActiveInspector().CurrentItem).Body.Trim();
                        m_goInspector = m_goOutlook.ActiveInspector();
                    }
                    if (lsBody == m_lsManagedEmailBody.Trim())
                    {
                        m_goInspector.Close(Outlook.OlInspectorClose.olDiscard);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }

    this does not close the Inspector but, on the other hand, it does not hang Outlook either.

    Tuesday, December 4, 2012 2:07 AM
  • I would do the absolute minimum processing necessary to add the Inspector.Activate() handler in NewInspector() and do no other processing there. Defer the other processing until Activate() fires.

    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "kptools" <=?utf-8?B?a3B0b29scw==?=> wrote in message news:1c9fd441-a624-415a-9567-3e27c5d71d9c...

    here's the redacted code:

          m_goOutlook is set to be the current Outlook application; m_goExplorer, m_goMailItem, and m_goInspector are properly declared variables

          public override void setOutlookEventsHandler()

            {
                //============ Set up the event handlers ===============
                try
                {
                    m_goOutlook.NewMail += new Outlook.ApplicationEvents_11_NewMailEventHandler(
                        m_goOutlook_NewMail);
                    m_goOutlook.ItemLoad += new Outlook.ApplicationEvents_11_ItemLoadEventHandler(
                        m_goOutlook_ItemLoad);
                    m_goExplorer.SelectionChange += new Outlook.ExplorerEvents_10_SelectionChangeEventHandler
                        (CurrentExplorer_Event);
                    m_goExplorer.ViewSwitch += new Outlook.ExplorerEvents_10_ViewSwitchEventHandler(
                        m_goExplorer_ViewSwitch);
                    m_goExplorer.FolderSwitch += new Outlook.ExplorerEvents_10_FolderSwitchEventHandler
                        (m_goOutlook_FolderSwitch);
                    m_goExplorer.BeforeItemCopy += new Outlook.ExplorerEvents_10_BeforeItemCopyEventHandler
                        (copyToNataero);
                    m_goExplorer.BeforeItemCut += new Outlook.ExplorerEvents_10_BeforeItemCutEventHandler
                        (cutToNataero);
                    m_goExplorer.BeforeItemPaste += new Outlook.ExplorerEvents_10_BeforeItemPasteEventHandler
                        (moveToNataero);
                    Outlook.Inspectors olInspectors = m_goOutlook.Inspectors;
                    olInspectors.NewInspector += new Outlook.InspectorsEvents_NewInspectorEventHandler(
                        m_goOutlook_NewInspector);
                    m_InspectorWindows = new List<Outlook.Inspector>();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("setOutlookEventsHandler: " + ex.Message);
                }
            }

            private void m_goOutlook_NewInspector(Outlook.Inspector toInspector)
            {
                try
                {
                    ((Outlook.InspectorEvents_10_Event)toInspector).Activate += new Outlook.InspectorEvents_10_ActivateEventHandler(
                        Inspector_Activate);
                    Outlook.MailItem loMailItem = toInspector.CurrentItem
                        as Outlook.MailItem;
                     ....

                     m_goMailItem = toInspector.CurrentItem;
                    m_goMailItem.AttachmentRead +=new Outlook.ItemEvents_10_AttachmentReadEventHandler(
                        m_goMailItem_AttachmentRead);
                    m_goMailItem.BeforeAttachmentPreview += new Outlook.ItemEvents_10_BeforeAttachmentPreviewEventHandler(
                        m_goMailItem_BeforeAttachmentPreview);
                    m_goMailItem.BeforeAttachmentRead +=new Outlook.ItemEvents_10_BeforeAttachmentReadEventHandler(
                        m_goMailItem_BeforeAttachmentRead);
                    if (<condition>)
                    {
                        //
                        //  if we are in a managed folder, open the file
                        //
                        m_loSelectedFolder = m_goExplorer.CurrentFolder;
                        if (isManagedFolder(m_loSelectedFolder.FolderPath.Trim()))
                        {
                            m_goMailItem = null;
                            Object selObject = m_goExplorer.Selection[1];
                            if (selObject is Outlook.MailItem)
                            {
                                //
                                //  m_goMailItem is now the dummy entry
                                //  in the Explorer window
                                //
                                m_goMailItem = (selObject as Outlook.MailItem);
                            }
                        }
                    }
                    //
                    //  if we open (e.g., load) the email
                    //  message succesfully, launch the viewer
                    //
                    if (<condition>)
                    {
                        if (openMailItem(m_liFileId))
                        {
                            m_goMailItem.Display();
                            finishOpen();
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                closeInfo();
            }

           private void finishOpen()
            {
                try
                {
                    if (<conditon>)
                    {
                        //
                        //  open the new inspector for this email
                        //
                        if (m_goMailItem != null)
                        {
                            m_goInspector = m_goMailItem.GetInspector;
                            ((Outlook.InspectorEvents_10_Event)m_goInspector).Close +=
                                new Outlook.InspectorEvents_10_CloseEventHandler(m_goInspector_Close);
                            m_goInspector.AttachmentSelectionChange += new Outlook.InspectorEvents_10_AttachmentSelectionChangeEventHandler(
                                m_goInspector_AttachmentSelectionChange);
                            ((Outlook.InspectorEvents_10_Event)m_goInspector).Activate += new Outlook.InspectorEvents_10_ActivateEventHandler(
                                Inspector_Activate);

                            //
                            m_goMailItem.AttachmentRead += new Outlook.ItemEvents_10_AttachmentReadEventHandler(
                                m_goMailItem_AttachmentRead);
                            m_goMailItem.BeforeAttachmentPreview += new Outlook.ItemEvents_10_BeforeAttachmentPreviewEventHandler(
                                m_goMailItem_BeforeAttachmentPreview);
                            m_goMailItem.BeforeAttachmentRead += new Outlook.ItemEvents_10_BeforeAttachmentReadEventHandler(
                                m_goMailItem_BeforeAttachmentRead);
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                closeInfo();
            }

            private void Inspector_Activate()
            {
                try
                {
                    String lsBody = String.Empty;
                    if (m_goOutlook.ActiveInspector() == null)
                    {
                        lsBody = ((Outlook.MailItem)m_goInspector.CurrentItem).Body.Trim();
                    }
                    else
                    {
                        lsBody = ((Outlook.MailItem)m_goOutlook.ActiveInspector().CurrentItem).Body.Trim();
                        m_goInspector = m_goOutlook.ActiveInspector();
                    }
                    if (lsBody == m_lsManagedEmailBody.Trim())
                    {
                        m_goInspector.Close(Outlook.OlInspectorClose.olDiscard);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }

    this does not close the Inspector but, on the other hand, it does not hang Outlook either.


    Ken Slovak MVP - Outlook
    Tuesday, December 4, 2012 6:18 PM
    Moderator
  • I'll try that and you know.  Thanks.
    Wednesday, December 5, 2012 1:16 AM
  • Well, I tried that. New_Inspector now only sets a local variable to be the new inspector passed to the event and subscribes that inspector to the activate event. In activate, i determine if the mail item is a managed one (actual message file is stored somewhere else) or a non-managed one. If non-managed, I basically do little other than subscribe to attachment open events. if managed, i (a) close and null that inspector, (b) close and null the mail item, (c) open a new mail item using OpenSharedItem, (d) reset the inspector local variable using the new mail item GetInspector. And viola! I still have two inspectors open (but the managed file loads into an inspector).
    Wednesday, December 5, 2012 11:01 PM
  • I would create a hidden Windows Form with a timer control on it and instantiate the form in the addin startup code. It will be running on the main Outlook thread. In your Activate() handler start the timer and set a variable identifying the Inspector to close. When the timer fires after you leave Activate() you can then safely close the Inspector.
     
    A System.Timers.Timer object can also be used if any calls made from the timer elapsed event are synched to the main Outlook thread. The Outlook object model should never be used from a background thread.

    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "kptools" <=?utf-8?B?a3B0b29scw==?=> wrote in message news:286460f0-b869-42cf-9ccd-63ad926892b8...
    Well, I tried that. New_Inspector now only sets a local variable to be the new inspector passed to the event and subscribes that inspector to the activate event. In activate, i determine if the mail item is a managed one (actual message file is stored somewhere else) or a non-managed one. If non-managed, I basically do little other than subscribe to attachment open events. if managed, i (a) close and null that inspector, (b) close and null the mail item, (c) open a new mail item using OpenSharedItem, (d) reset the inspector local variable using the new mail item GetInspector. And viola! I still have two inspectors open (but the managed file loads into an inspector).

    Ken Slovak MVP - Outlook
    • Marked as answer by kptools Friday, December 7, 2012 11:52 PM
    Thursday, December 6, 2012 2:53 PM
    Moderator
  • well that (or actually, a variant) worked.  thanks for you help and insight.
    Friday, December 7, 2012 11:51 PM