简体   繁体   中英

Microsoft.Office.Interop.Outlook

I am using the Microsoft.Office.Interop.Outlook.Application interface I can get Outlook events to record OK if:

a) Outlook is already running when my application starts,

b) If Outlook started once my application is running. (To do this I had to change default permissions of the Monitoring tool application from admin to normal user – to stop COM complaining about type mis-matches)

BUT I cannot get the application to register outlook events if:

c) The Outlook app is quit, during run-time and then re-started (during run-time).

Basically – the application handles a NewExplorer event OK for (b) above, but once an open outlook app has been quit – this event handler is no longer called. I have done some checks, and at the time of the Quit event – the NewExplorer event is still assigned. But then obviously becomes unassigned before the next outlook open. I've tried assigning it when the user clicks on the Outlook app button (so just before it opens) and this doesn't produce any runtime error, but this does not solve the problem.

…So currently if a user starts using Outlook, then shuts it and then restarts, only events from the first Outlook session will be recorded.

The OutlookEventListener class that I am using is pasted below. It is instantiated on the main application form.

Regards 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;
        }
    }
}

It looks like you need to develop an Outlook add where you can all Outlook events. See Walkthrough: Creating Your First Application-Level Add-in for Outlook to get started quickly.

If you need to get any information from a standalone application you can use standard mechanism for inter-process communications (for example, WCF - .Net Remoting) to access the running instance of your managed add-in.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM