如何判断Outlook 2010邮件发送是否未被取消?
解决Outlook 2010加载项ItemSend被取消后的数据保存问题
我之前踩过Outlook事件顺序的坑,这种多个加载项抢占ItemSend事件的情况确实头疼,给你几个实用的方案,避开直接在ItemSend里同步执行保存操作:
方案1:延迟检查邮件发送状态
在你的ItemSend事件里,不要立即保存数据,而是先记录下当前邮件的EntryID(唯一标识),然后用定时器延迟几百毫秒(比如500-1000ms),再通过这个EntryID重新获取邮件对象,检查它的状态:
- 如果邮件的
Sent属性为True,或者邮件所在的文件夹是「已发送邮件」,说明发送成功,再执行数据保存操作 - 如果获取不到邮件(被Outlook清理)或者
Sent为False,说明发送被取消,放弃保存
示例代码(VBA)
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean) ' 记录邮件ID,不要直接保存数据 Dim mailEntryID As String mailEntryID = Item.EntryID ' 延迟1秒执行检查 Application.OnTime Now + TimeValue("00:00:01"), "CheckMailSentStatus", , True End Sub Sub CheckMailSentStatus() Dim objMail As MailItem On Error Resume Next ' 通过EntryID获取邮件 Set objMail = Application.Session.GetItemFromID(mailEntryID) On Error GoTo 0 If Not objMail Is Nothing Then If objMail.Sent = True Then ' 发送成功,执行你的数据保存逻辑 SaveDataToService objMail End If Set objMail = Nothing End If End Sub
方案2:监听「已发送邮件」文件夹的新增事件
直接放弃在ItemSend里触发操作,转而监听「已发送邮件」文件夹的ItemAdd事件——只有当邮件真正发送成功并被移动到这个文件夹时,才执行数据保存:
- 先获取「已发送邮件」文件夹的引用
- 注册
ItemAdd事件,当有新邮件添加时,触发你的保存逻辑
核心思路(C#示例片段)
Outlook.MAPIFolder sentFolder = Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail); sentFolder.ItemAdd += SentFolder_ItemAdd; private void SentFolder_ItemAdd(object Item) { if (Item is Outlook.MailItem mail) { // 确认是刚发送的邮件,执行数据保存 SaveDataToExternalService(mail); } }
方案3:暂存邮件信息,后续验证
如果你的数据保存需要依赖邮件发送时的实时状态(比如用户最后一刻修改的内容),可以在ItemSend里把邮件的关键信息(主题、收件人、正文等)暂存到内存或临时文件,然后用方案1的延迟检查逻辑,确认发送成功后再把暂存的数据提交到服务。
注意事项
- 定时器的延迟时间要根据实际情况调整,确保Outlook有足够时间处理完所有加载项的
ItemSend事件 - 获取邮件时要处理异常,避免因邮件被删除或移动导致的报错
- 如果你用的是VSTO加载项,注意不要在非UI线程操作Outlook对象,需要切换回UI线程执行
内容的提问来源于stack exchange,提问作者Maderas
相关产品推荐
相关产品推荐

