Outlook interop code throws “message has been changed” error the second time when the code tries to save a mail item

耗尽温柔 提交于 2019-12-25 11:55:12

问题


First of all, this problem only happens on a few client machines and I can not replicate it on any of my test machines.

So I have the following test code in 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);

The second mail.Save() call has a 100% rate on these few client machines to throw the exception: System.Runtime.InteropServices.COMException (0x80040109): The operation cannot be performed because the message has been changed.

Since the above code properly releases the first mail object and retrieves the second mail object using entry ID again. The chance to have something changing the mail object between the second retrieval of the object and calling its Save() method is very low, not to mention the 100% reproducible rate.

I can only think that it looks like a bug in Outlook that it may permanently mark a mail object as changed as soon as anything calls the Save() method once.

Does any one know if there is a work around?

These machines are using the latest version of Office 2016.


回答1:


IMAP4 is one of the worst - every time you try to touch any of the store objects, it tries to sync. You can try to bypass the IMAP4 layer and go directly to the PST provider used as the underlying local storage. In Extended MAPI (C++ or Delphi), you can do that using the IProxyStoreObject interface. In case of languages other than C++ or Delphi, you can use Redemption and its RDOSession.Stores.UnwrapStore method - the message can be then opened from the unwrapped store using RDOStore.GetMessageFromID.



来源:https://stackoverflow.com/questions/46460902/outlook-interop-code-throws-message-has-been-changed-error-the-second-time-whe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!