Outlook VSTO:邮件进入已发送箱时调用函数获取发送日期失败
问题:Outlook已发送邮件箱ItemAdd事件无法触发
我想实现当邮件进入Outlook的已发送邮件箱(Sent Items)时,调用函数获取该邮件的发送日期(Sent Date),但当前代码无法正常工作。最初的代码在ThisAddIn_Startup方法中遍历Stores,绑定的是**收件箱(Inbox)**的Items.ItemAdd事件;后续将items改为全局变量后,还是无法触发已发送邮件箱的事件。
初始代码
private void ThisAddIn_Startup(object sender, System.EventArgs e) { try { Outlook.Stores stores = Application.Session.Stores; foreach (Outlook.Store store in stores) { var folder = store.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox); var items = folder.Items; if (items.Count > 0) MessageBox.Show($"Unread items in Inbox = {items.Count}"); items.ItemAdd += ItemsAdd; } } catch (Exception exception) { Log.Error(exception.Message); throw; } }
更新后代码
Outlook.Items items; private void ThisAddIn_Startup(object sender, System.EventArgs e) { try { Outlook.Stores stores = Application.Session.Stores; foreach (Outlook.Store store in stores) { var folder = store.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox); items = folder.Items; items.ItemAdd += ItemsAdd; } } catch (Exception exception) { Log.Error(exception.Message); throw; } }
修复方案
- 目标文件夹错误:你的代码一直绑定的是收件箱(
olFolderInbox),要监听已发送邮件箱,需要改用olFolderSentMail枚举值。 - 全局变量覆盖问题:遍历多个Store时,全局
items变量会被最后一个Store的收件箱Items覆盖,导致之前的绑定失效。需要用集合存储每个Store的已发送邮件箱Items对象,避免被垃圾回收或覆盖。
修复后的代码示例:
// 用集合存储所有已发送邮件箱的Items对象,防止被GC回收 private List<Outlook.Items> _sentItemsCollection = new List<Outlook.Items>(); private void ThisAddIn_Startup(object sender, System.EventArgs e) { try { Outlook.Stores stores = Application.Session.Stores; foreach (Outlook.Store store in stores) { // 获取当前Store的已发送邮件箱 var sentFolder = store.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail); var sentItems = sentFolder.Items; // 绑定ItemAdd事件 sentItems.ItemAdd += SentItems_ItemAdd; // 添加到集合中保存引用 _sentItemsCollection.Add(sentItems); } } catch (Exception exception) { Log.Error(exception.Message); throw; } } // 已发送邮件箱ItemAdd事件处理方法 private void SentItems_ItemAdd(object item) { if (item is Outlook.MailItem mail) { // 获取发送日期 DateTime sentDate = mail.SentOn; // 这里添加你的业务逻辑,比如打印或记录发送日期 MessageBox.Show($"邮件发送日期:{sentDate.ToString("yyyy-MM-dd HH:mm:ss")}"); } }
关键说明
- 使用
store.GetDefaultFolder而非store.Session.GetDefaultFolder:前者会获取当前Store对应的默认文件夹,后者可能返回当前会话的默认Store文件夹,避免跨Store的错误。 - 用集合保存
Outlook.Items引用:Outlook对象模型中,局部变量的Items对象容易被垃圾回收,导致事件失效,全局集合可以维持引用。 - 类型判断:在事件处理方法中先判断item是否为
MailItem,避免非邮件项触发错误。
内容的提问来源于stack exchange,提问作者gabrielcassimiro
相关产品推荐
相关产品推荐

