Outlook互操作代码抛出"邮件已被更改"代码尝试保存邮件项时第二次出错

时间:2017-09-28 04:17:42

标签: c# email outlook outlook-addin

首先,这个问题只发生在一些客户端计算机上,我无法在我的任何测试计算机上复制它。

所以我在LINQPad中有以下测试代码:

var application = new Application();
var session = application.Session;
const string entryId = "arbitrary entry ID";
const string propertyName = "http://schemas.microsoft.com/mapi/string/{31A9B8DA-D4A0-4B96-87AE-01D6E9BCFCCE}/Test/0x0000001F";

// Save test property for the first time.
var mail = (MailItem)session.GetItemFromID(entryId);
var propertyAccessor = mail.PropertyAccessor;
propertyAccessor.SetProperty(propertyName, 1);
mail.Save();

Marshal.ReleaseComObject(propertyAccessor);
Marshal.ReleaseComObject(mail);

// Save test property for the second time.
mail = (MailItem)session.GetItemFromID(entryId);
var propertyAccessor = mail.PropertyAccessor;
propertyAccessor.SetProperty(propertyName, 2);
mail.Save();

Marshal.ReleaseComObject(propertyAccessor);
Marshal.ReleaseComObject(mail);
Marshal.ReleaseComObject(session);
Marshal.ReleaseComObject(application);

第二次mail.Save()调用在这几台客户端计算机上具有100%的速率以抛出异常:System.Runtime.InteropServices.COMException (0x80040109): The operation cannot be performed because the message has been changed.

由于上面的代码正确地释放了第一个mail对象,并再次使用条目ID检索第二个mail对象。在对象的第二次检索和调用其mail方法之间更改Save()对象的机会非常低,更不用说100%可重现的速率了。

我只能认为它看起来像Outlook中的一个错误,只要有人调用Save()方法一次就可以永久标记邮件对象。

有没有人知道是否有解决方法?

这些计算机使用的是最新版本的Office 2016。

1 个答案:

答案 0 :(得分:1)

IMAP4是最差的之一 - 每当您尝试触摸任何商店对象时,它都会尝试同步。您可以尝试绕过IMAP4层并直接转到用作底层本地存储的PST提供程序。在扩展MAPI(C ++或Delphi)中,您可以使用IProxyStoreObject接口执行此操作。对于C ++或Delphi以外的语言,您可以使用Redemption及其RDOSessionStoresUnwrapStore方法 - 然后可以使用已解包的商店打开该消息RDOStoreGetMessageFromID