【问题标题】:Get sent message in Outlook Addin在 Outlook 插件中获取已发送的消息
【发布时间】:2014-11-24 05:46:36
【问题描述】:

我在尝试从 Outlook 插件获取已发送消息时遇到一些问题。

onItemSend 事件中,我打开一个对话框,其中显示了一些字段,其中包含收件人、主题等消息信息以及将这些信息保存到我们的数据库中的按钮。另一个要求是保存已发送消息的副本,这就是我卡住的地方......

我可以使用 SaveAs 方法保存消息,但问题是当我打开消息时,它显示:

此消息尚未发送。此消息将通过发送 微软交换

给用户造成一些问题,让他们认为消息没有发送。

在搜索过程中,我发现 this thread 另一个人遇到了同样的问题,解决方案是在 PostItem 在已发送状态下创建后,将消息用作 PostItem 而不是 MailItem。另外,我们应该将 MessageClass 属性设置为 IPM.Note 并删除 PR_ICON_INDEX

这是我用来执行上述步骤的代码。我找到了这段代码here,并稍作改动:

PostItem postItem = this._email.Application.CreateItem(OlItemType.olPostItem);
postItem.MessageClass = "IPM.Note";
PropertyAccessor pa = postItem.PropertyAccessor;
pa.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x10800003", -1);
postItem.Save();

NameSpace session = postItem.Session;
string postItemEntryID = postItem.EntryID;
Marshal.ReleaseComObject(postItem);
Marshal.ReleaseComObject(pa);

MailItem newMessage = session.GetItemFromID(postItemEntryID) as MailItem;
newMessage.BCC = this._email.BCC;
newMessage.Body = this._email.Body;
newMessage.BodyFormat = this._email.BodyFormat;
newMessage.CC = this._email.CC;
newMessage.HTMLBody = this._email.HTMLBody;

//Hard coded path just for illustration
newMessage.SaveAs("C:\\Temp\\MSG\test.msg", OlSaveAsType.olMSG); 

上面的代码创建了一个postitem对象,设置了一些属性并正确保存到路径,但是存在以下问题:

  1. 执行postItem.save后,为了创建postitem消息,它会在收件箱文件夹中创建一条已读消息

  2. 保存邮件后,我比较了文件和重要的大小,原始邮件大小为 580kb,postitem 保存的邮件为 52kb。好像没有复制邮件

  3. 它丢失了一些嵌入在消息中的图像,例如签名图像,在适当的位置显示一个红色 X。

如何获取/创建具有确切消息内容、收件人、附件、属性等(克隆类型)和已发送状态的消息,而无需在收件箱文件夹中创建另一条消息?

谢谢

【问题讨论】:

  • 拜托,我必须实现这样的东西,你能提供我的源代码,或者指出我可以找到解决方案的地方,我需要将一些电子邮件存储到我们的数据库中。你是怎么做到的?
  • 请看this。在此示例中,它显示了如何获取传入的电子邮件并对其进行处理。如果您需要发送项目,请添加如下处理程序: this.itemsendhndler = new Microsoft.Office.Interop.Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend); this.Application.ItemSend += itemsendhndler;.让我知道您是否需要其他任何东西。 :)

标签: c# email outlook outlook-addin


【解决方案1】:

我不会对 Outlook 尝试发送的邮件执行此操作。你可以

  1. 处理已发送邮件文件夹中的 Items.ItemAdd 事件。到那时,消息已发送,所有与发件人相关的属性都已设置。

  2. 您可以通过删除未发送标志来“修复”创建的 MSG 文件。您可以使用Redemption 执行此操作 - 调用 RDOSession.GetMessageFromMsgFile / RDOMail.Sent = true / RDOMail.Save。请记住,发件人信息可能尚未设置。

【讨论】:

  • 嗨,德米特里!只是关于您的第一个建议的问题...我在某处读到用户可以更改已发送项目文件夹。如果用户更改此文件夹,我能否收到发送的消息?我必须在 itemAdd 事件之前设置发送的文件夹吗?如果我更改发送的文件夹位置,它会覆盖用户的选项吗?感谢您的建议
  • 您可以跟踪 Application.ItemSend 事件并检查 MailItem.SaveSentMessageFolder 属性是否指向由 Namespace.GetDefaultFolder 返回的预期 Sent Items 文件夹(使用 Namespace..CompareEntryIds)。然后,您也可以跟踪该文件夹上的 ItemAdd 事件,或者将自定义文件夹的条目 ID 保存在自定义属性 (MailItem.UserProperties) 中,并将 SaveSentMessageFolder 属性重置为默认的已发送邮件文件夹。当您在该文件夹上处理 ItemAdd 时,您可以使用自定义属性打开自定义文件夹并将消息移动到那里。
  • 嗨,Dmitry,您能否解释一下如何“跟踪该文件夹上的 ItemAdd 事件”。这是否意味着定义类似“Public WithEvents justinreserve1 As Outlook.Items”,然后将其用于该文件夹?
  • 您可以拥有一个 Items 对象列表,而不是拥有一个指向 Items 对象的变量 - 这样您就可以拥有任意数量的 Items 全部被引用以确保它们不会被释放。您使用的是 C# 还是 VB?
  • 我正在使用 vb。听起来很有趣你有一个链接,我可以找到更多信息吗?
【解决方案2】:

我不会更进一步地使用“postitem”,不知何故它看起来对我来说不是完美的方式。

问题是您在发送之前复制了该项目。因此,副本说它尚未发送。 如果您不需要保存在“已发送项目”文件夹中的“普通”副本,您可以更改保存项目的文件夹

Set mailitem.SaveSentMessageFolder = someother Folder '(which is defined as Outlook.folder)

如果这不可能,那么我会检查(在 ThisOutlookSession 中)“已发送项目”文件夹,并为其中的每个新项目执行复制操作。如果你不知道如何让我知道,那么我复制一些代码给你,让你上路。

另一个问题只是因为我很好奇:您为什么要打开表单并等待某人点击确定按钮,而不是立即将数据保存到您的数据库中?

【讨论】:

  • 嗨,Max,谢谢您的建议。我会尝试...关于您的好奇心,我在表单上显示另一个字段,用户将在其中添加注释,从一些下拉列表中选择一些数据,然后当用户点击确定按钮时,它将保存所有用户选择和消息本身。我只是没有在表格上写下所有发生的事情:) 谢谢
  • 嗨,“已发送项目”文件夹的“检查(在 ThisOutlookSession 中)”与 Dimitri 的建议相同,尽管他当然有更好的解释。同样在这里,这仅在用户没有更改已发送项目文件夹的情况下才有效,或者甚至使用 vba 逐个进行此操作。
猜你喜欢
  • 2017-07-06
  • 1970-01-01
  • 1970-01-01
  • 2021-05-05
  • 1970-01-01
  • 2013-01-11
  • 2016-05-19
  • 1970-01-01
  • 2011-10-04
相关资源
最近更新 更多