如何从Outlook VSTO的MailItem访问数字签名并添加自定义签名属性?
Outlook OnSent事件中签名处理与自定义属性留存方案
一、提取并更新签名数据+留存自定义属性
首先明确:Outlook的签名本质是邮件正文(HTML/RTF/纯文本)的一部分,没有单独的“签名数据对象”,但可以通过以下方式处理:
- 提取签名:优先在
ItemSend事件(发送前触发,更适合修改)中操作。HTML格式下,签名通常位于<div class="WordSection1">之后,或通过MailItem.GetInspector.WordEditor调用Word对象模型,定位最后几个段落(签名段落特征明显);RTF/纯文本格式可通过字符串分割或段落索引提取。 - 留存自定义属性:普通
UserProperties在邮件发送/转换时易丢失,必须使用MAPI命名空间属性:
用Redemption的RDOItem.Fields添加属性,示例代码:
这类命名空间属性会被Outlook全程保留,不会被清理。Set rdoMsg = CreateObject("Redemption.RDOMail") rdoMsg.MAPIOBJECT = MailItem.MAPIOBJECT rdoMsg.Fields("http://schemas.yourdomain.com/props#CustomSignatureAttr") = "自定义属性值" rdoMsg.Save
二、Redemption转换SecureMailMessage时EntryId未设置的解决
出现该问题是因为SecureMailMessage需要关联已持久化的MAPI对象,解决步骤:
- 若在
ItemSend事件:先将MailItem临时保存到草稿箱生成EntryId,再用Redemption加载:MailItem.Save ' 保存到草稿获取EntryId Set rdoSession = CreateObject("Redemption.RDOSession") rdoSession.MAPIOBJECT = Application.Session.MAPIOBJECT Set rdoMsg = rdoSession.GetMessageFromID(MailItem.EntryID) Set secureMsg = rdoMsg.SecureMailMessage ' 处理签名与属性后保存 rdoMsg.Save - 若在
OnSent事件:直接从已发送文件夹获取对应MailItem的EntryId,再用Redemption加载即可,无需临时保存。
三、重新创建MailItem并保证格式不受影响
要完整保留原邮件格式,需复制所有格式相关属性与内容:
- 直接复制核心格式字段:HTML格式复制
HTMLBody,RTF格式复制RTFBody字节数组,同时同步BodyFormat、Subject、收件人、附件等基础属性。 - 用Redemption的
RDOMail.CopyTo方法可完整复制所有属性(包括自定义属性与格式):
该方式能100%保留原邮件格式,同时携带自定义属性。Set rdoSession = CreateObject("Redemption.RDOSession") rdoSession.MAPIOBJECT = Application.Session.MAPIOBJECT Set rdoMsg = rdoSession.GetMessageFromID(原邮件EntryId) Set newRdoMsg = rdoSession.CreateMessageFromMsgFile("temp.msg") rdoMsg.CopyTo newRdoMsg, 0 ' 0表示复制所有属性 Set newMailItem = Application.Session.GetItemFromID(newRdoMsg.EntryID)
关键注意点
- 优先使用
ItemSend事件而非OnSent:OnSent时邮件已完成发送,修改需重新触发发送流程,ItemSend可在发送前完成所有修改,避免冗余操作。 - 所有自定义属性必须使用MAPI命名空间属性,禁止使用
UserProperties.Add,后者在邮件传输或Outlook内部转换时极易丢失。 - Redemption操作必须关联有效的MAPI对象(通过
MAPIOBJECT或EntryId),否则会触发EntryId未设置的错误。
内容的提问来源于stack exchange,提问作者mihai stoica
相关产品推荐
相关产品推荐

