我正在使用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;
}
}
}
答案 0 :(得分:0)
您似乎需要开发Outlook添加,您可以在其中执行所有Outlook事件。请参阅Walkthrough: Creating Your First Application-Level Add-in for Outlook以快速入门。
如果您需要从独立应用程序获取任何信息,您可以使用标准机制进行进程间通信(例如,WCF - .Net Remoting)来访问托管加载项的运行实例。