Outlook VSTO:如何实现全邮箱类型下获取正确邮件发送日期?
问题:获取Outlook邮件正确发送日期的实现优化方案
我需要实现一个功能:在邮件发送时调用函数获取正确的Sent Date(发送日期),为此完成了两种实现,但均存在缺陷:
private void ThisAddIn_Startup(object sender, System.EventArgs e) { //First implementation. try { Outlook.Stores stores = Application.Session.Stores; foreach (Outlook.Store store in stores) { var folder = store.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail); items = folder.Items; items.ItemAdd += ItemsAdd; } } catch (Exception exception) { Log.Error(exception.Message); throw; } //Second implementation. this.Application.ItemSend += new Microsoft.Office.Interop.Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend); }
两种实现的缺陷:
- 第一种实现:监听各邮箱的已发送邮件文件夹
ItemAdd事件,可获取正确的发送日期,但对POP3类型的邮箱账户无效; - 第二种实现:监听
Application.ItemSend事件,支持所有邮箱类型,但获取的发送日期不正确。
请问能否优化第一种实现使其支持POP3账户,或提供其他可行的解决方案?
解决方案
优化第一种实现以支持POP3账户
第一种实现失效的核心原因是:原代码使用store.Session.GetDefaultFolder会指向当前会话的默认存储,而非遍历的目标store对应的存储,导致POP3账户的已发送文件夹未被正确监听。调整获取文件夹的逻辑即可解决:
private void ThisAddIn_Startup(object sender, System.EventArgs e) { try { Outlook.Stores stores = Application.Session.Stores; foreach (Outlook.Store store in stores) { // 直接从当前Store对象获取关联的默认已发送文件夹 Outlook.Folder sentFolder = store.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail) as Outlook.Folder; if (sentFolder != null) { var items = sentFolder.Items; items.ItemAdd += ItemsAdd; } } } catch (Exception exception) { Log.Error(exception.Message); throw; } }
改用store.GetDefaultFolder可以精准获取当前Store对应的已发送邮件文件夹,适配POP3账户的存储逻辑。
替代方案:结合两种事件的优势
如果优化后仍存在边缘场景问题,可以结合两种事件的特性实现:
- 在
Application.ItemSend事件中,记录待发送邮件的临时唯一标识(比如Subject+SenderEmailAddress+当前时间戳的组合,因为POP3邮件发送前可能还未生成有效EntryID); - 在
ItemAdd事件中捕获已存入已发送文件夹的邮件,匹配之前记录的标识,此时即可读取到准确的SentOn属性(发送日期)。
这种方式既覆盖了所有邮箱类型,又能保证拿到正确的发送日期。
注意事项
- 若使用
EntryID作为标识,需注意POP3邮件在发送前可能尚未生成有效EntryID,此时必须用临时组合标识; - 监听
Items.ItemAdd事件后,处理完成要及时释放COM对象,避免内存泄漏; - 部分POP3账户可能被用户设置为不保存已发送邮件,这种情况下
ItemAdd事件不会触发,需提示用户开启“保存已发送邮件”的设置。
内容的提问来源于stack exchange,提问作者gabrielcassimiro
相关产品推荐
相关产品推荐

