Outlook VSTO - ActiveInspector 返回错误的电子邮件窗口信息

时间:2021-01-10 00:53:59

标签: c# email outlook vsto outlook-addin

我试图从我之前在 Outlook 中打开(双击)的电子邮件中获取信息。代码工作正常,直到我打开多封电子邮件。我发现当我点击一封电子邮件时,检查器会激活,但我从最后一个活动窗口获取信息,而不是我点击的当前窗口。

这是我的代码:

using Outlook = Microsoft.Office.Interop.Outlook;
using System.Diagnostics;
using System.Threading;

namespace OutlookWindowActivateTest
{
    public partial class ThisAddIn
    {
        //Outlook.Inspectors OurInspectors;
        Outlook.Inspector ActiveInspector;
        Outlook.MailItem ActiveMailItem;

        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            Debug.WriteLine("LOADING CODE");
            Application.Inspectors.NewInspector += new Outlook.InspectorsEvents_NewInspectorEventHandler(Mail_Debugger);
        }

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
            // Note: Outlook no longer raises this event. If you have code that 
            //    must run when Outlook shuts down, see https://go.microsoft.com/fwlink/?LinkId=506785
        }

        public void Mail_Debugger(Outlook.Inspector Inspector)
        {
            Debug.WriteLine("###START DEBUGS VOID MAIL INSPECTOR###");
            // This will fire when an email item is opened in its own window WILL NOT FIRE if you just preview
            if (Inspector.CurrentItem is Outlook.MailItem)
            {
                // this part is correct when I doubleclick an email to open it
                Outlook.MailItem OpenedMailItem = Inspector.CurrentItem as Outlook.MailItem;
                Debug.WriteLine($"  Email doubleclicked -> MailItem details:");
                Debug.WriteLine($"      Subject: {OpenedMailItem.Subject}");
                Debug.WriteLine($"      To: {OpenedMailItem.To}");
                Debug.WriteLine($"      From name: {OpenedMailItem.Sender.Name}");
                Debug.WriteLine($"      From email: {OpenedMailItem.Sender.Address}");
                Debug.WriteLine($"      Conversation ID: {OpenedMailItem.ConversationID}");
                Debug.WriteLine($"  Opened email is {OpenedMailItem.Subject}");
                ((Outlook.InspectorEvents_Event)Inspector).Activate += new Outlook.InspectorEvents_ActivateEventHandler(InspectorActivate);
                ((Outlook.InspectorEvents_Event)Inspector).Deactivate += new Outlook.InspectorEvents_DeactivateEventHandler(InspectorDeactivate);
                ((Outlook.InspectorEvents_Event)Inspector).Close += new Outlook.InspectorEvents_CloseEventHandler(InspectorClose);
                Inspector.PageChange += new Outlook.InspectorEvents_10_PageChangeEventHandler(InspectorPageChange);
            }
            Debug.WriteLine($"  Number of inspectors is {Application.Inspectors.Count}");
            Debug.WriteLine("       Inspector info:");
            foreach (Outlook.Inspector insp in Application.Inspectors)
            {
                Debug.WriteLine($"      Inspector is {insp.Caption}");
            }
            Debug.WriteLine("###END DEBUGS VOID MAIL INSPECTOR###");
        }

        private void InspectorPageChange(ref string page)
        {
            // this also happens when you doubleclick an email in outlook to open it
            Debug.WriteLine("Inspector page has changed");
            Debug.WriteLine($"      {page}");

        }
        private void InspectorClose()
        {
            Debug.WriteLine("Inspector has closed");
        }

        private void InspectorActivate()
        {
            Debug.WriteLine("Inspector was activated by someone clicking on an outlook window that is NOT the base window");
            ActiveInspector = Application.ActiveInspector();
            if (ActiveInspector is null)
            {
                Debug.WriteLine("The inspector is null because it is not ready....");
            }
            else
            {
                Debug.WriteLine($"Caption is {ActiveInspector.Caption}");
                object selectedItem = ActiveInspector.CurrentItem;
                if (selectedItem != null)
                {
                    if (selectedItem is Outlook.MailItem)
                    {
                        ActiveMailItem = selectedItem as Outlook.MailItem;
                        Debug.WriteLine($"ACTIVE INSPECTOR -> MailItem details:");
                        Debug.WriteLine($"      Subject: {ActiveMailItem.Subject}");
                        Debug.WriteLine($"      To: {ActiveMailItem.To}");
                        Debug.WriteLine($"      From name: {ActiveMailItem.Sender.Name}");
                        Debug.WriteLine($"      From email: {ActiveMailItem.Sender.Address}");
                        Debug.WriteLine($"      Conversation ID: {ActiveMailItem.ConversationID}");
                    }
                }
            }
                
        }

        private void InspectorDeactivate()
        {

            Debug.WriteLine("Inspector was deactivated");
            //if (ActiveMailItem != null)
            //{
            //    Debug.WriteLine($"  INSPECTOR -> OLD MailItem details:");
            //    Debug.WriteLine($"      Subject: {ActiveMailItem.Subject}");
            //    Debug.WriteLine($"      To: {ActiveMailItem.To}");
            //    Debug.WriteLine($"      From name: {ActiveMailItem.Sender.Name}");
            //    Debug.WriteLine($"      From email: {ActiveMailItem.Sender.Address}");
            //    Debug.WriteLine($"      Conversation ID: {ActiveMailItem.ConversationID}");
            //    Debug.WriteLine($"");
            //}
        }


        #region VSTO generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }

        #endregion
    }
}

我花了很长时间研究这个,但显然我遗漏了一些东西。 我觉得在尝试获取 Active Inspector 之前,我需要等待活动检查器/当前项目发生变化。我在网上看了一下,发现了一些链接,包括这个:

https://social.msdn.microsoft.com/Forums/en-US/a17733ec-4420-4c7a-aa6a-23a9c9ee68e1/how-to-get-the-mail-item-opened-window?forum=outlookdev

但这和其他人一样并不是我想要的,因为我不是在与新的检查员打交道。我正在处理一个已经打开的,并且只是在 2 个或多个打开的检查员之间工作。

“Mail_Debugger”功能似乎工作正常 - 当我在 Outlook 中双击一封电子邮件,当它打开时,我会得到我刚刚打开的正确电子邮件的信息。

最后,我的目标是通过在 Outlook 中双击打开多个电子邮件,然后在他们自己的窗口中打开,然后单击这些电子邮件窗口以获取活动检查器,该检查器应该能够在窗口。

知道我做错了什么吗? 谢谢你

2 个答案:

答案 0 :(得分:0)

您的 library(dplyr, warn.conflicts = F) library(tidyr) df1 <- data.frame(ID = c("a","b","c","d","e"), var1 = c(10,15,12,14,NA)) df2 <- data.frame(Name = c("Nr1","Nr2","Nr100","Nr76"), a_xyz = c(100, 120,130,NA), b_xyz = c(150,NA,80,90), c_xyz = c(120,120,NA,140), d_xyz = c(140,130,150,180), e_xyz = c(130,120,100,150)) df1 <- df1 %>% pivot_wider(names_from = ID, values_from = var1) df3 <- df2 %>% mutate(a_xyz = a_xyz / df1$a, b_xyz = b_xyz / df1$b, c_xyz = c_xyz / df1$c, d_xyz = d_xyz / df1$d, e_xyz = e_xyz / df1$e) df3 #> Name a_xyz b_xyz c_xyz d_xyz e_xyz #> 1 Nr1 10 10.000000 10.00000 10.000000 NA #> 2 Nr2 12 NA 10.00000 9.285714 NA #> 3 Nr100 13 5.333333 NA 10.714286 NA #> 4 Nr76 NA 6.000000 11.66667 12.857143 NA 事件永远不会触发 - 您正在为编译器创建的隐式变量设置事件处理程序 - 一旦 GC 释放它,该事件将不再触发。您必须保持变量引发事件处于活动状态。

NewInspectorCreated

答案 1 :(得分:0)

经过大量的反复试验,我想我终于解决了这个问题。上面的一点是想出另一种方式的一个重要考虑因素 - activeinspector 不可见,因此您不能简单地调用它,因为如果您之前发布了该项目,它将始终为空,或者它将等于最后找到的 activeinspector。这是我解决这个问题的方法 - 我的代码并不完美,但它确实可以按预期工作而无需调用另一个线程。另外从我的阅读来看,最好不要对您的代表有强烈的引用(这不是我的问题,但仍然是一个好习惯) 我的前进方向是获取活动窗口而不是活动检查器并将其转换为检查器。

using Outlook = Microsoft.Office.Interop.Outlook;
using System.Diagnostics;
using System.Threading;
using System.Runtime.InteropServices;

namespace OutlookWindowActivateTest
{
    public partial class ThisAddIn
    {
        Outlook.Inspectors MyInspectors;
        Outlook.Inspector activeInspector;
        Outlook.MailItem ActiveMailItem;
        Outlook.InspectorsEvents_NewInspectorEventHandler InspectorEventHandler;
        Outlook.InspectorEvents_ActivateEventHandler inspectorEvents_Activate;
        Outlook.InspectorEvents_DeactivateEventHandler inspectorEvents_Deactivate;
        Outlook.InspectorEvents_CloseEventHandler inspectorEvents_Close;

        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            Debug.WriteLine("LOADING CODE");
            InspectorEventHandler = new Outlook.InspectorsEvents_NewInspectorEventHandler(NewInspectorCreated);
            inspectorEvents_Activate = new Outlook.InspectorEvents_ActivateEventHandler(InspectorActivate);
            inspectorEvents_Deactivate = new Outlook.InspectorEvents_DeactivateEventHandler(InspectorDeactivate);
            inspectorEvents_Close = new Outlook.InspectorEvents_CloseEventHandler(InspectorClose);
            MyInspectors = Application.Inspectors;
            MyInspectors.NewInspector += InspectorEventHandler;
        }

        public void NewInspectorCreated(Outlook.Inspector Inspector)
        {
            activeInspector = Inspector;
            Debug.WriteLine("###START DEBUGS VOID MAIL INSPECTOR###");
            // This will fire when an email item is opened in its own window WILL NOT FIRE if you just preview
            if (activeInspector.CurrentItem is Outlook.MailItem)
            {
                // this part is correct when I doubleclick an email to open it
                Outlook.MailItem OpenedMailItem = activeInspector.CurrentItem as Outlook.MailItem;
                Debug.WriteLine($"  Email doubleclicked -> MailItem details:");
                Debug.WriteLine($"      Subject: {OpenedMailItem.Subject}");
                Debug.WriteLine($"      To: {OpenedMailItem.To}");
                Debug.WriteLine($"      From name: {OpenedMailItem.Sender.Name}");
                Debug.WriteLine($"      From email: {OpenedMailItem.Sender.Address}");
                Debug.WriteLine($"      Conversation ID: {OpenedMailItem.ConversationID}");
                Debug.WriteLine($"  Opened email is {OpenedMailItem.Subject}");
                // add these events to capture when an opened email window is clicked on , closed or clicked away from
                ((Outlook.InspectorEvents_Event)activeInspector).Activate += inspectorEvents_Activate;
                ((Outlook.InspectorEvents_Event)activeInspector).Deactivate += inspectorEvents_Deactivate;
                ((Outlook.InspectorEvents_Event)activeInspector).Close += inspectorEvents_Close;
            }
            Debug.WriteLine($"  Number of inspectors is {Application.Inspectors.Count}");
            Debug.WriteLine("       Inspector info:");
            foreach (Outlook.Inspector insp in Application.Inspectors)
            {
                Debug.WriteLine($"      Inspector is {insp.Caption}");
            }
            Debug.WriteLine("###END DEBUGS VOID MAIL INSPECTOR###");
        }
        private void InspectorClose()
        {
            Debug.WriteLine("Inspector has closed");
            // work to do here
        }
        private void InspectorActivate()
        {
            Debug.WriteLine("Inspector was activated by someone clicking on an outlook window that is NOT the base window");
            var ThisWindow = Application.ActiveWindow();
            if (ThisWindow is Outlook.Inspector)
            {
                Debug.WriteLine("This window is an inspector");
                activeInspector = ThisWindow as Outlook.Inspector;
                activeInspector.Activate();
                if (activeInspector.CurrentItem is Outlook.MailItem)
                {
                    ActiveMailItem = activeInspector.CurrentItem;
                    Debug.WriteLine("The active inspector is a mail item");
                    Debug.WriteLine($"ACTIVE INSPECTOR -> MailItem details:");
                    Debug.WriteLine($"      Subject: {ActiveMailItem.Subject}");
                    Debug.WriteLine($"      To: {ActiveMailItem.To}");
                    Debug.WriteLine($"      From name: {ActiveMailItem.Sender.Name}");
                    Debug.WriteLine($"      From email: {ActiveMailItem.Sender.Address}");
                    Debug.WriteLine($"      Conversation ID: {ActiveMailItem.ConversationID}");
                }
            }
            else
            {
                Debug.WriteLine("It is something else"); // I end up here when I open an email in a new window the first time (i.e. double click it)

            }
        }
       
        private void InspectorDeactivate()
        {
            Debug.WriteLine("This Inspector is being deactivated");
            // more work to do here
        }

        #region VSTO generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }
        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
            // Note: Outlook no longer raises this event. If you have code that 
            //    must run when Outlook shuts down, see https://go.microsoft.com/fwlink/?LinkId=506785
        }

        #endregion
    }
}

使用此代码,当我第一次双击打开电子邮件时,我没有看到活动窗口,但我可以在其他地方处理它,所以这对我来说不是问题。这段代码对我的作用是让我点击在它自己的窗口中打开的电子邮件,并将该窗口作为检查员。从这里,我可以找到任何信息是需要的有问题的电子邮件。

相关问题