Outlook 2016 VSTO文件夹添加事件仅触发一次。

3

我正在创建一个Outlook插件来跟踪邮箱中的邮件处理。我正在包装文件夹和项目(添加一些事件),并将它们存储在本地列表中,以避免GC在第一次执行后清除所有事件。然而,文件夹添加事件仅触发一次。不确定问题出在哪里。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using OutlookNS = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
using System.Net;
using System.Windows.Forms;


namespace OutlookAuditor
{
    public partial class ThisAddIn
    {
        #region private variables

        OutlookNS._NameSpace outNS;
        OutlookNS.Explorer explorer;
        string profileName = string.Empty;
        List<SuperMailFolder> wrappedFolders = new List<SuperMailFolder>();
        Logger logger = new Logger();
        SuperMailFolder folderToWrap;
        #endregion

        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            try
            {
                OutlookNS.Application application = this.Application;

                //Get the MAPI namespace
                outNS = application.GetNamespace("MAPI");
                //Get UserName
                string profileName = outNS.CurrentUser.Name;

                //Create a new outlook application
                //I had to do this because my systems default mail box was ost file other just the below commented line is enough
                //OutlookNS.MAPIFolder inbox = outNS.GetDefaultFolder(OutlookNS.OlDefaultFolders.olFolderInbox) as OutlookNS.MAPIFolder;
                OutlookNS.MAPIFolder inbox;
                OutlookNS.Folders folders = outNS.Folders;
                OutlookNS.MAPIFolder selectedFolder = null;
                if (folders.Count > 1)
                {

                    List<string> folderNames = new List<string>();
                    foreach (OutlookNS.Folder folder in folders)
                    {
                        folderNames.Add(folder.Name);
                    }
                    using (selectMailBox frmSelect = new selectMailBox(folderNames))
                    {

                        if (DialogResult.OK == frmSelect.ShowDialog())
                        {
                            selectedFolder = folders[frmSelect.SelectedFolder];
                        }
                    }


                }
                else
                {
                    selectedFolder = folders[1];
                }
                logger.SaveLog("Folder Selected " + selectedFolder.Name);
                inbox = selectedFolder.Folders["Inbox"];//as OutlookNS.MAPIFolder;
                //Create a super mail folder
                folderToWrap = new SuperMailFolder(inbox, profileName);
                wrappedFolders.Add(folderToWrap);
                wrappedFolders.AddRange(folderToWrap.wrappedSubFolders);

                //System.Runtime.InteropServices.Marshal.ReleaseComObject(inbox);
            }
            catch (Exception ex)
            {
                logger.WriteException(ex);
            }
            finally
            {

            }
        }

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }

        #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
    }

    #region SuperMailItem object
    class SuperMailItem
    {
        //local variable for avoiding GC invocation
        OutlookNS.MailItem item;
        string _profileName;
        OutlookAuditor.Common.AuditItem auditItem;
        string parentMailID;
        string _folderName = string.Empty;
        OutlookNS.MailItem replyItem;
        Logger logger = new Logger();
        //constructor that wraps mail item with required events
        internal SuperMailItem(OutlookNS.MailItem MailItemToWrap, string profileName,string folderName)
        {
            try
            {
                item = MailItemToWrap as OutlookNS.MailItem;

                _folderName = folderName;
                if (item is OutlookNS.MailItem)
                {
                    logger.SaveLog(item.Subject);
                    item.PropertyChange += MailItemToWrap_PropertyChange;
                    //item.PropertyChange += new OutlookNS.ItemEvents_10_PropertyChangeEventHandler(MailItemToWrap_PropertyChange);

                    ((OutlookNS.ItemEvents_10_Event)item).Reply += SuperMailItem_Reply;
                }
            }
            catch(Exception ex)
            {
                logger.WriteException(ex,"SuperMailItem Constructor");
            }

        }

        void SuperMailItem_Reply(object Response, ref bool Cancel)
        {
            try
            {
                parentMailID = string.Empty;
                replyItem = Response as OutlookNS.MailItem;
                ((OutlookNS.ItemEvents_10_Event)replyItem).Send += SuperMailItem_Send;
            }
            catch(Exception ex)
            {
                logger.WriteException(ex);
            }

        }


        //this event is not firing
        void SuperMailItem_Send(ref bool Cancel)
        {
            try
            {
                if (!Cancel)
                {
                    createAuditItem();
                    auditItem.ActionDescription = "REPLY_SENT";
                    SaveLog();
                }
            }
            catch(Exception ex)
            {
                logger.WriteException(ex);
            }

        }

        //property change event- fires when any property of a mail item changes
        void MailItemToWrap_PropertyChange(string Name)
        {
            try
            {

                createAuditItem();
                //We are interested in UnRead property, if this property changes audit.
                if (Name == "UnRead")
                {
                    if (!item.UnRead)
                    {
                        auditItem.ActionDescription = "MAIL_READ";
                    }
                    else
                    {
                        auditItem.ActionDescription = "MAIL_UNREAD";
                    }
                }
                SaveLog();
            }
            catch(Exception ex)
            {
                logger.WriteException(ex);
            }
        }

        void createAuditItem()
        {
            auditItem = new Common.AuditItem();
            auditItem.ActionTimestamp = DateTime.Now;
            auditItem.EntryID = item.EntryID;
            auditItem.ProfileName = _profileName;
            auditItem.ReceivedTimestamp = item.ReceivedTime;
            auditItem.SystemIP = Helper.SystemIP();
            auditItem.UserName = Helper.UserID();
            auditItem.OriginalMailSentBy = item.Sender.Name;
            auditItem.FolderName = _folderName;
            auditItem.Subject = item.Subject;
        }

        void SaveLog()
        {
            Logger logger = new Logger();
            logger.Save(auditItem);
        }
    }

    #endregion

    #region SuperMailFolder object
    class SuperMailFolder
    {
        #region private variables
        OutlookNS.MAPIFolder _wrappedFolder;
        string _profileName;
        List<SuperMailItem> wrappedItems = new List<SuperMailItem>();
        public List<SuperMailFolder> wrappedSubFolders = new List<SuperMailFolder>();
        string folderName = string.Empty;
        Logger logger = new Logger();
        #endregion

        #region constructor
        internal SuperMailFolder(OutlookNS.MAPIFolder folder, string profileName)
        {
            try
            {
                //assign it to local private master
                _wrappedFolder = folder;
                folderName = folder.Name;
                _profileName = profileName;
                //assign event handlers for the folder
                _wrappedFolder.Items.ItemAdd +=Items_ItemAdd;
                _wrappedFolder.Items.ItemRemove += Items_ItemRemove;

                refreshItemList();

                //Go through all the subfolders and wrap them as well
                foreach (OutlookNS.MAPIFolder tmpFolder in _wrappedFolder.Folders)
                {
                    logger.SaveLog("Wrapping folder " + tmpFolder.Name);
                    SuperMailFolder tmpWrapFolder = new SuperMailFolder(tmpFolder, _profileName);
                    wrappedSubFolders.Add(tmpWrapFolder);
                    wrappedSubFolders.AddRange(tmpWrapFolder.wrappedSubFolders);
                }

            }
            catch(Exception ex)
            {
                logger.WriteException(ex);
            }
        }
        #endregion

        void Items_ItemRemove()
        {
            refreshItemList();
        }

        #region Handler of addition item into a folder
        void Items_ItemAdd(object Item)
        {
            try
            {
                if (Item is OutlookNS.MailItem)
                {

                    OutlookNS.MailItem item = Item as OutlookNS.MailItem;

                    wrappedItems.Add(new SuperMailItem(item, _profileName, folderName));
                    logger.SaveLog("Adding new item. New collection count:" + wrappedItems.Count.ToString());
                    OutlookAuditor.Common.AuditItem auditItem = new Common.AuditItem();
                    auditItem.ActionTimestamp = DateTime.Now;
                    auditItem.EntryID = item.EntryID;
                    auditItem.ProfileName = _profileName;
                    auditItem.ReceivedTimestamp = item.ReceivedTime;
                    auditItem.SystemIP = Helper.SystemIP();
                    auditItem.UserName = Helper.UserID();
                    auditItem.ActionDescription = "FOLDER_ADD";
                    auditItem.FolderName = folderName;
                    auditItem.OriginalMailSentBy = item.Sender.Name;
                    auditItem.Subject = item.Subject;
                    logger.Save(auditItem);
                }
            }
            catch(Exception ex)
            {
                logger.WriteException(ex);
            }
        }

        void refreshItemList()
        {

            try
            {
                wrappedItems.Clear();
                wrappedItems = new List<SuperMailItem>();
                logger.SaveLog("Wrapping items in " + folderName);
                //Go through all the items and wrap it.
                foreach (OutlookNS.MailItem item in _wrappedFolder.Items)
                {
                    try
                    {
                        if (item is OutlookNS.MailItem)
                        {
                            OutlookNS.MailItem mailItem = item as OutlookNS.MailItem;
                            SuperMailItem wrappedItem = new SuperMailItem(mailItem, _profileName, folderName);
                            wrappedItems.Add(wrappedItem);
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.WriteException(ex);
                    }
                }
                logger.SaveLog("Wrapped items in " + folderName + ":" + wrappedItems.Count.ToString());
            }
            catch(Exception ex)
            {
                logger.WriteException(ex);
            }
        }
        #endregion
    }
    #endregion

    static class Helper
    {
        public static string SystemIP()
        {
            string hostName = Dns.GetHostName();
            string hostAddress = Dns.GetHostByName(hostName).AddressList[0].ToString();
            return hostAddress;
        }

        public static string UserID()
        {
            return System.Security.Principal.WindowsIdentity.GetCurrent().Name;
        }
    }
}
1个回答

5
以下代码是问题所在:

以下代码是问题所在:

        _wrappedFolder.Items.ItemAdd +=Items_ItemAdd;
        _wrappedFolder.Items.ItemRemove += Items_ItemRemove;

触发事件的对象必须是活着的 - 在你的情况下,你在从_wrappedFolder.Items属性返回的隐式变量上设置了一个事件处理程序 - 一旦GC释放了那个隐式变量,就不会再有事件触发。在类级别上声明Items对象以确保它保持引用和存活。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接