Microsoft.Office.Interop.Outlook

时间:2015-04-23 16:10:41

标签: c# .net outlook office-interop

我正在使用Microsoft.Office.Interop.Outlook.Application接口我可以在以下情况下获取Outlook事件以便记录:

a)我的应用程序启动时Outlook已经在运行,

b)如果我的应用程序运行后Outlook启动了。 (为此,我必须将监控工具应用程序的默认权限从管理员更改为普通用户 - 以阻止COM抱怨类型不匹配)

但如果出现以下情况,我无法让应用程序注册outlook事件:

c)Outlook应用程序在运行期间退出,然后重新启动(在运行时)。

基本上 - 应用程序处理上面(b)的NewExplorer事件OK,但是一旦打开Outlook应用程序已经退出 - 不再调用此事件处理程序。 我做了一些检查,在Quit事件发生时 - 仍然分配了NewExplorer事件。但在下一次展望开放之前,显然会被取消分配。 我尝试在用户点击Outlook应用程序按钮时进行分配(就在它打开之前),这不会产生任何运行时错误,但这并不能解决问题。

...因此,如果用户开始使用Outlook,然后关闭它然后重新启动,则只会记录第一个Outlook会话中的事件。

我正在使用的OutlookEventListener类粘贴在下面。它在主申请表上实例化。

此致 AG

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

using MonitoringTool.Common;

namespace MonitoringTool.OfficeInterop
{
    public class OutlookEventListener: OfficeEventListener
    {
        public Outlook.Application outlookApp;
        private const string PR_SMTP_ADDRESS = "http://schemas.microsoft.com/mapi/proptag/0x39FE001E";

        private Outlook.Explorer explorer;
        private Outlook.Explorers explorers;
        private Outlook.Folder deletefolder;
        private Outlook.MailItem mailitem;
        private string itemid = "", openitemid = "";



        public OutlookEventListener(NLogger observerLogger)
        {
            outlookApp = new Outlook.Application();

            outlookApp.Startup += new Outlook.ApplicationEvents_11_StartupEventHandler(outlookApp_Startup);
            outlookApp.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(outlookApp_ItemSend);
            outlookApp.NewMailEx += new Outlook.ApplicationEvents_11_NewMailExEventHandler(outlookApp_NewMailEx);
            (outlookApp as Outlook.ApplicationEvents_11_Event).Quit += new Outlook.ApplicationEvents_11_QuitEventHandler(outlookApp_Quit);

            deletefolder = outlookApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderDeletedItems) as Outlook.Folder;
            deletefolder.Items.ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(ItemDelete);

            //Outlook.Folder inboxfolder = outlookApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) as Outlook.Folder;
            //inboxfolder.BeforeItemMove += new Outlook.MAPIFolderEvents_12_BeforeItemMoveEventHandler(ItemMove);

            explorers = outlookApp.Explorers;
            if (outlookApp.Explorers.Count > 0)
            {
                explorer = outlookApp.ActiveExplorer();
                explorer.FolderSwitch += new Outlook.ExplorerEvents_10_FolderSwitchEventHandler(explorer_FolderSwitch);
                explorer.SelectionChange += new Outlook.ExplorerEvents_10_SelectionChangeEventHandler(explorer_SelectionChange);
                (explorer.CurrentFolder as Outlook.Folder).BeforeItemMove += 
                    new Outlook.MAPIFolderEvents_12_BeforeItemMoveEventHandler(ItemMove);
            }
            else  
            {

                explorers.NewExplorer +=
                    new Outlook.ExplorersEvents_NewExplorerEventHandler(outlookApp_NewExplorer);
            }

            outlookApp.Inspectors.NewInspector += new Outlook.InspectorsEvents_NewInspectorEventHandler(inspectors_NewInspector);
            RegisterObserver(observerLogger);
            Observer.OutlookReady();
        }

        private void outlookApp_Startup()
        {
            LoggerEventArgs e = new LoggerEventArgs();
            e.LogTime = string.Format("[{0:HH:mm:ss.fff}]", DateTime.Now);
            e.MessageLevel = LoggerMessageLevel.Level3;
            e.MessageType = MessageType.OUTL_START_APP;
            e.MessageText = ""; 

            Observer.LogEvent(e);
        }

        private void outlookApp_ItemSend(Object Item, ref bool Cancel)
        {
            Outlook.MailItem newMailItem = outlookApp.ActiveInspector().CurrentItem as Outlook.MailItem;

            LoggerEventArgs e = new LoggerEventArgs();
            e.LogTime = string.Format("[{0:HH:mm:ss.fff}]", DateTime.Now);
            e.MessageLevel = LoggerMessageLevel.Level3;
            e.MessageType = MessageType.OUTL_SEND_EMAIL;
            e.MessageText = "SUBJECT=" + newMailItem.Subject + "; " +
                "RECIPIENTS=" + GetSMTPAddressForRecipients(newMailItem) + "; " +
                "BODY=" + newMailItem.Body; 
            Observer.LogEvent(e);
        }

        private string GetSMTPAddressForRecipients(Outlook.MailItem mail)
        {
            Outlook.Recipients recips = mail.Recipients;
            string strrecips = "";

            foreach (Outlook.Recipient recip in recips)
            {
                Outlook.PropertyAccessor pa = recip.PropertyAccessor;
                string smtpAddress = pa.GetProperty(PR_SMTP_ADDRESS).ToString();
                if (!string.IsNullOrEmpty(strrecips))
                    strrecips += ", ";
                strrecips += recip.Name + " (" + smtpAddress + ")";
            }

            return strrecips;
        }

        private void outlookApp_NewMailEx(string entryID)
        {
            try
            { 
                Outlook.NameSpace outlookNS = outlookApp.GetNamespace("MAPI");
                Outlook.MAPIFolder folder = outlookApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
                if (outlookNS != null)
                {
                    Outlook.MailItem mailItem = outlookNS.GetItemFromID(entryID, folder.StoreID) as Outlook.MailItem;

                    Outlook.PropertyAccessor pa = mailItem.Sender.PropertyAccessor;
                    string smtpAddress = pa.GetProperty(PR_SMTP_ADDRESS).ToString();

                    LoggerEventArgs e = new LoggerEventArgs();
                    e.LogTime = string.Format("[{0:HH:mm:ss.fff}]", DateTime.Now);
                    e.MessageLevel = LoggerMessageLevel.Level3;
                    e.MessageType = MessageType.OUTL_RECEIVE_MAIL;
                    e.MessageText = "SUBJECT=" + mailItem.Subject + "; " +
                        "RECIPIENTS=" + GetSMTPAddressForRecipients(mailItem) + "; " +
                        "BODY=" + mailItem.Body; 
                    Observer.LogEvent(e);
                }
            }
            catch (Exception e) 
            {
                ErrorLogEventArgs err = new ErrorLogEventArgs();
                err.LogTime = string.Format("[{0:HH:mm:ss.fff}]", DateTime.Now);
                err.MessageText = e.Message;
                err.StackTrace = e.StackTrace; 

                Observer.LogException(err);
            }
        }

        private void outlookApp_Quit()
        {
            LoggerEventArgs e = new LoggerEventArgs();
            e.LogTime = string.Format("[{0:HH:mm:ss.fff}]", DateTime.Now);
            e.MessageLevel = LoggerMessageLevel.Level3;
            e.MessageType = MessageType.OUTL_QUIT_APP;
            e.MessageText = "";             
            Observer.LogEvent(e);

            // At this point: explorers = outlookApp.Explorers ... ie not Null

        }

        private void ItemDelete(object item)
        {
            LoggerEventArgs e = new LoggerEventArgs();
            e.LogTime = string.Format("[{0:HH:mm:ss.fff}]", DateTime.Now);
            e.MessageLevel = LoggerMessageLevel.Level3;
            e.MessageType = MessageType.OUTL_DELETE_MAIL;
            e.MessageText = (item as Outlook.MailItem).Subject; 

            Observer.LogEvent(e);
        }

        private void ItemMove(Object Item, Outlook.MAPIFolder MoveTo, ref bool Cancel)
        {
            LoggerEventArgs e = new LoggerEventArgs();
            e.LogTime = string.Format("[{0:HH:mm:ss.fff}]", DateTime.Now);
            e.MessageLevel = LoggerMessageLevel.Level3;
            e.MessageType = MessageType.OUTL_MOVE_MAIL;
            e.MessageText = MoveTo.Name; 

            Observer.LogEvent(e);
        }


        // This event handler only gets called when Outlook application has not been 'quit' during runtime.

        public void outlookApp_NewExplorer(Outlook.Explorer Explorer)
        {
            if (explorer == null)
            {
                LoggerEventArgs e = new LoggerEventArgs();
                e.LogTime = string.Format("[{0:HH:mm:ss.fff}]", DateTime.Now);
                e.MessageLevel = LoggerMessageLevel.Level3;
                e.MessageType = MessageType.OUTL_START_APP;
                e.MessageText = "";
                Observer.LogEvent(e); 

                explorer = outlookApp.ActiveExplorer();
                explorer.FolderSwitch += new Outlook.ExplorerEvents_10_FolderSwitchEventHandler(explorer_FolderSwitch);
                explorer.SelectionChange += new Outlook.ExplorerEvents_10_SelectionChangeEventHandler(explorer_SelectionChange);
            }
        }        

        private void explorer_FolderSwitch()
        {
            (explorer.CurrentFolder as Outlook.Folder).BeforeItemMove +=
                new Outlook.MAPIFolderEvents_12_BeforeItemMoveEventHandler(ItemMove);
            deletefolder.Items.ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(ItemDelete);

            LoggerEventArgs e = new LoggerEventArgs();
            e.LogTime = string.Format("[{0:HH:mm:ss.fff}]", DateTime.Now);
            e.MessageLevel = LoggerMessageLevel.Level3;
            e.MessageType = MessageType.OUTL_SWITCH_FOLDER;
            e.MessageText = explorer.CurrentFolder.Name; 

            Observer.LogEvent(e);
        }

        private void explorer_SelectionChange()
        {
            try
            {
                if (explorer.Selection.Count > 0)
                {
                    Object selObject = explorer.Selection[1];
                    if (selObject is Outlook.MailItem)
                    {
                        mailitem = (selObject as Outlook.MailItem);

                        if (!itemid.Equals(mailitem.EntryID))
                        {
                            itemid = mailitem.EntryID;

                            mailitem.Open += mailitem_Open;
                            (mailitem as Outlook.ItemEvents_10_Event).Reply += mailitem_Reply;
                            (mailitem as Outlook.ItemEvents_10_Event).ReplyAll += mailitem_ReplyAll;
                            (mailitem as Outlook.ItemEvents_10_Event).Forward += mailitem_Forward;

                            (explorer.CurrentFolder as Outlook.Folder).BeforeItemMove +=
                                new Outlook.MAPIFolderEvents_12_BeforeItemMoveEventHandler(ItemMove);
                            deletefolder.Items.ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(ItemDelete);

                            LoggerEventArgs e = new LoggerEventArgs();                            
                            e.LogTime = string.Format("[{0:HH:mm:ss.fff}]", DateTime.Now);
                            e.MessageLevel = LoggerMessageLevel.Level3;
                            e.MessageType = MessageType.OUTL_CHANGE_SEL;
                            e.MessageText = mailitem.Subject; 

                            Observer.LogEvent(e);
                            LoggerEventArgs e2 = new LoggerEventArgs();
                            if (mailitem.UnRead)
                                e2.LogTime = string.Format("[{0:HH:mm:ss.fff}]", DateTime.Now);
                                e2.MessageLevel = LoggerMessageLevel.Level3;
                                e2.MessageType = MessageType.OUTL_READ_MAIL;
                                e2.MessageText = mailitem.Subject;
                                Observer.LogEvent(e2);
                        }
                    }
                }
            }
            catch //(Exception ex)
            {
                //outlook is closing
                return;
            }
        }

        private void mailitem_Open(ref bool Cancel)
        {
            if (!openitemid.Equals(mailitem.EntryID))
            {
                openitemid = mailitem.EntryID;

                LoggerEventArgs e = new LoggerEventArgs(); 
                e.LogTime = string.Format("[{0:HH:mm:ss.fff}]", DateTime.Now);
                e.MessageLevel = LoggerMessageLevel.Level3;
                e.MessageType = MessageType.OUTL_OPEN_MAIL;
                e.MessageText = mailitem.Subject; 

                Observer.LogEvent(e);
            }
        }

        private void mailitem_Reply(Object Response, ref bool Cancel)
        {
            LoggerEventArgs e = new LoggerEventArgs();
            e.LogTime = string.Format("[{0:HH:mm:ss.fff}]", DateTime.Now);
            e.MessageLevel = LoggerMessageLevel.Level3;
            e.MessageType = MessageType.OUTL_REPLY_MAIL;
            e.MessageText = mailitem.Subject; 

            Observer.LogEvent(e);
        }

        private void mailitem_ReplyAll(Object Response, ref bool Cancel)
        {
            LoggerEventArgs e = new LoggerEventArgs();
            e.LogTime = string.Format("[{0:HH:mm:ss.fff}]", DateTime.Now);
            e.MessageLevel = LoggerMessageLevel.Level3;
            e.MessageType = MessageType.OUTL_REPLY_ALL;
            e.MessageText = mailitem.Subject; 

            Observer.LogEvent(e);
        }

        private void mailitem_Forward(Object Item, ref bool Cancel)
        {
            LoggerEventArgs e = new LoggerEventArgs();
            e.LogTime = string.Format("[{0:HH:mm:ss.fff}]", DateTime.Now);
            e.MessageLevel = LoggerMessageLevel.Level3;
            e.MessageType = MessageType.OUTL_FORWARD_MAIL;
            e.MessageText = (Item as Outlook.MailItem).Subject; 

            Observer.LogEvent(e);
        }

        private void inspectors_NewInspector(Outlook.Inspector Inspector)
        {
            if (!(Inspector.CurrentItem as Outlook.MailItem).Sent)
            {
                LoggerEventArgs e = new LoggerEventArgs();
                e.LogTime = string.Format("[{0:HH:mm:ss.fff}]", DateTime.Now);
                e.MessageLevel = LoggerMessageLevel.Level3;
                e.MessageType = MessageType.OUTL_COMPOSE_MAIL;
                e.MessageText = "";

                Observer.LogEvent(e);
            }
        }

        ~OutlookEventListener()
        {
            Dispose(false);
        }

        public override void Dispose()
        {
            LoggerEventArgs e = new LoggerEventArgs();
            e.LogTime = string.Format("[{0:HH:mm:ss.fff}]", DateTime.Now);
            e.MessageLevel = LoggerMessageLevel.StatusUpdate;
            e.MessageType = MessageType.OUTLOOK_WATCHER;
            e.MessageText = "Closing Outlook Monitor."; 

            Observer.LogStatus(e); 
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposed)
                return;

            try
            {
                if (disposing)
                {
                    // Free any other managed objects here.
                    //if (outlookApp != null)
                    //    (outlookApp as Outlook._Application).Quit();
                }

                // Free any unmanaged objects here. 
            }
            catch (Exception e) 
            {
                ErrorLogEventArgs err = new ErrorLogEventArgs();
                err.LogTime = string.Format("[{0:HH:mm:ss.fff}]", DateTime.Now);
                err.MessageText = e.Message;
                err.StackTrace = e.StackTrace; 

                Observer.LogException(err);
            }

            disposed = true;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您似乎需要开发Outlook添加,您可以在其中执行所有Outlook事件。请参阅Walkthrough: Creating Your First Application-Level Add-in for Outlook以快速入门。

如果您需要从独立应用程序获取任何信息,您可以使用标准机制进行进程间通信(例如,WCF - .Net Remoting)来访问托管加载项的运行实例。