none
MailItem Save error because message has changed

    Question

  • Hi,

    I'have a vsto outlook addin, it was migrated from OLK 2003 to OLK 2010 (using VS 2010sp1), so all references to CDO was deleted.

    Now I'm using Redemption to work with MAPI fields (insted of CDO), in some situations I get an error when wants to save a new MAPI field in the mailitem, the error comes because the "message has changed", so the method Save fails:

    Public Shared Sub SetCampoMAPIcon_RED(ByVal xItem As Outlook.MailItem, ByVal xsCampo As String, ByVal xsValor As String) Try Dim sItem As New Redemption.SafeMailItem, PR_MY_PROP As Object 'sItem = CreateObject("Redemption.SafeMailItem") sItem.Item = xItem PR_MY_PROP = sItem.GetIDsFromNames("{00020329-0000-0000-C000-000000000046}", xsCampo) Or &H101E 'PT_UNICODE Dim PropValue(0) As String PropValue(0) = xsValor sItem.Fields(PR_MY_PROP) = PropValue 'to convince Outlook something has changed sItem.Item.Subject = sItem.Item.Subject sItem.Save()'FAIL

    xItem.Save() 'ReleaseCOMobject(sItem) Catch ex As System.Exception GeneroTrace("SetCampoMAPIconRedemption::", TraceLevel.Error, ex.Message & vbCrLf & ex.StackTrace & vbCrLf & xsCampo & " - " & xsValor) End Try End Sub

    I could reproduce this error if I have two sessions opens in two PCs, then I open a mail in PC1, then open the same mail in PC2 and close it, then in PC1 when I close the mail comes that error.

    This happen because my addin set mapi fields when mails open, so my question is why using CDO in 2003 it did not happened?

    thanks a lot,

    Mauricio.


    Mauricio

    Thursday, December 20, 2012 7:07 PM

Answers

  • Hmmm... You can force Redemption to overwrite the changes (note that when you call Safe*Item.Save, the call call goes to the original Outlook item since the Save method is not blocked)

    If you are using the latest version of Redemption, you can try something like the following script.

    The latest version of Redemption (since RDOMail.Save does not take any parameters) will allow to call SaveAs with an empty file name. In that case the second parameter is interpreted as a parameter to pass to IMessage::SaveChanges(); this way you can pass the FORCE_SAVE parameter.

    KEEP_OPEN_READWRITE = 00000002
    FORCE_SAVE = 00000004
    set Session = CreateObject("Redemption.RDOSession")
    Session.MAPIOBJECT = Application.Session.MAPIOBJECT
    rMail = Session.GetRDOObjectFromOutlookObject(xItem)
    rMail.SaveAs("", FORCE_SAVE | KEEP_OPEN_READWRITE)


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.4 is now available!


    Saturday, January 05, 2013 5:24 PM

All replies

  • It is all in the timing - if you are using a cached store, it is possible that the local cached store will not see the change made on another machine until after you save the item. Or it could be that CDO 1.21 simply ignored the error.

    There isn't much you can do - a conflict is a conflict: you can simply ignore the error or you can use Redemption to overwrite the changes anyway.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.4 is now available!

    Thursday, December 20, 2012 8:20 PM
  • Hi Dmitry,

    we didn't use the OLK cache, that CDO just ignored the error....

    The problem is that after this error mailitem "saved" property change to "false", so when the mailitem is closed a pop up dialog appears asking to save the changes... there is anyway to avoid this?

    thanks,

    Mauricio.


    Mauricio

    Thursday, December 20, 2012 8:48 PM
  • Have you tried to call MailItem.Close(olDiscard)?

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.4 is now available!

    Monday, December 24, 2012 3:13 PM
  • but I'm already attached to the mailItem close event, so when you suggests to use "MailItem.Close(olDiscard)" ?

    (when the user closes a mail, the close event fires and all events go on in the chain....)

    thanks.


    Mauricio

    Thursday, December 27, 2012 2:59 PM
  • Hmmm... You can force Redemption to overwrite the changes (note that when you call Safe*Item.Save, the call call goes to the original Outlook item since the Save method is not blocked)

    If you are using the latest version of Redemption, you can try something like the following script.

    The latest version of Redemption (since RDOMail.Save does not take any parameters) will allow to call SaveAs with an empty file name. In that case the second parameter is interpreted as a parameter to pass to IMessage::SaveChanges(); this way you can pass the FORCE_SAVE parameter.

    KEEP_OPEN_READWRITE = 00000002
    FORCE_SAVE = 00000004
    set Session = CreateObject("Redemption.RDOSession")
    Session.MAPIOBJECT = Application.Session.MAPIOBJECT
    rMail = Session.GetRDOObjectFromOutlookObject(xItem)
    rMail.SaveAs("", FORCE_SAVE | KEEP_OPEN_READWRITE)


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.4 is now available!


    Saturday, January 05, 2013 5:24 PM