none
Duplicate mail coming when i save mail item in outlook 2007 & 2010. RRS feed

  • Question

  • Hi All,

    If i am working on an outlook plugin.

    Following is code snippet which i used to save mail with some modification, i can see two mails on server ( IMAP account )

    one mail with original content and other with modified content.

    following code snippet may help.


    //Here i can get new mail notification.
    void __stdcall CAddin::OnNewMailEx(BSTR bstrEntryID)

    //Here i can get Mail item using bstrEntryID
    CComVariant vOptional(DISP_E_PARAMNOTFOUND, VT_ERROR);
    CComPtr<IDispatch> pItemDisp;
    CComQIPtr<Outlook::_MailItem> pMailItem;

    hr = pNameSpace->GetItemFromID(bstrEntryID, vOptional, &pItemDisp);
    if (FAILED(hr))
    {
    return false;
    }
    pMailItem = pItemDisp;


    //Following call save the mail item.
    hr = pMailItem->Save();
    Saturday, August 29, 2015 7:58 AM

Answers

  • This topic shows a code sample in C++ that queries a message store for the IProxyStoreObject interface.

    Its an IMsgStore interface pointer that you should obtain from the Outlook Store object.

    • Marked as answer by rsquareshelke Monday, September 7, 2015 8:25 AM
    Wednesday, September 2, 2015 11:32 AM
  • You can retrieve it from Store.MAPIOBJECT in the Outlook Object Model.

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

    • Marked as answer by rsquareshelke Monday, September 7, 2015 8:25 AM
    Wednesday, September 2, 2015 3:01 PM
  • You can bypass the IMAP4 layer and modify the underlying PST message using IProxyStoreObject for the store object (you can then use the IMsgStore object to open the message by its entry id) or you can use IMAPISecureMessage interface to get to the native IMessage object from the PST store.  Both of these require Extended MAPI (C++ or Delphi).  If using Redemption is an option, it exposes RDOSession.Stores.UnwrapStore and RDOSession.GetRDOObjectFromOutlookObject (set the last parameter to true to unwrap the object).

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

    • Marked as answer by rsquareshelke Monday, September 7, 2015 8:25 AM
    Saturday, August 29, 2015 9:41 PM

All replies

  • Hello,

    Could you specify the build number of your Outlook?

    Make sure that latest updates and service packs are installed for Outlook/Office.

    Saturday, August 29, 2015 9:51 AM
  • Hey, thanks for your reply, i am having below version installed:

    and it is happening with all outlook 2007, 2010 only not for 2013.

    Outlook Version: Outlook (14.0.4734.1000) MSO (14.0.4734.1000)

    How can i avoid this?

    Your reply will help me a lot.

    Saturday, August 29, 2015 11:27 AM
  • IMAP4 provider s infamous for creating duplicates when you manipulate and save messages that were not yet completely downloaded. Try to wait until the item is completely downloaded and process the item only when MailItem.DownloadState == 1 (OlDownloadState.olFullItem).

    Your NewMailEx event hander can add the entry id to a list to be processed later (timer?). 


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

    Saturday, August 29, 2015 7:07 PM
  • Hi All,

    If i am working on an outlook plugin.

    Following is code snippet which i used to save mail with some modification, i can see two mails on server ( IMAP account )

    one mail with original content and other with modified content.

    following code snippet may help.


    //Here i can get new mail notification.
    void __stdcall CAddin::OnNewMailEx(BSTR bstrEntryID)

    //Here i can get Mail item using bstrEntryID
    CComVariant vOptional(DISP_E_PARAMNOTFOUND, VT_ERROR);
    CComPtr<IDispatch> pItemDisp;
    CComQIPtr<Outlook::_MailItem> pMailItem;

    hr = pNameSpace->GetItemFromID(bstrEntryID, vOptional, &pItemDisp);
    if (FAILED(hr))
    {
    return false;
    }
    pMailItem = pItemDisp;


    //Following call save the mail item.
    hr = pMailItem->Save();
    Looks like we've come full circle on this -- https://social.msdn.microsoft.com/Forums/office/en-US/06d89b6c-91df-44e7-b288-a544395d3233/outlook-imap-acccount-duplicate-mails-on-server-if-i-save-mail-body-outlook-2007-2010-?forum=outlookdev
    Saturday, August 29, 2015 7:25 PM
  • You can bypass the IMAP4 layer and modify the underlying PST message using IProxyStoreObject for the store object (you can then use the IMsgStore object to open the message by its entry id) or you can use IMAPISecureMessage interface to get to the native IMessage object from the PST store.  Both of these require Extended MAPI (C++ or Delphi).  If using Redemption is an option, it exposes RDOSession.Stores.UnwrapStore and RDOSession.GetRDOObjectFromOutlookObject (set the last parameter to true to unwrap the object).

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

    • Marked as answer by rsquareshelke Monday, September 7, 2015 8:25 AM
    Saturday, August 29, 2015 9:41 PM
  • Does the unwrapped store returned from IProxyStoreObject::UnwrapNoRef bypass synchronization in both directions(il.e. uploads to the IMAP4 server as well as downloads)?  The documentation seems to speak only to avoiding dowloads.

    Saturday, August 29, 2015 11:07 PM
  • Yes, it bypasses the sync in both directions - it is just an IMsgStore from the underlying PST provider. In a sense that the IMAP4 provider would have no idea that an object was modified and it needs to be uploaded to the remote IMAP4 server. Most common use however is reading the objects without triggering the expensive and error prone sync with the IMAP4 server.


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

    Sunday, August 30, 2015 12:01 AM
  • Hi Thanks for your reply,

    As you said,

    "you can then use the IMsgStore object to open the message by its entry id."

    When and how can i achieve that because, i can not parse until the message is downloaded fully.

    Can i do when user click on the mail, as i can get itemchange event's as well.

    but how i can i check with item change event is for which entry ID?

    i hope it clears.

    your reply can help me a lot.

    many thanks



    Tuesday, September 1, 2015 11:10 AM
  • Check the MailItem.DownloadState property first. ItemChnage event passes the item as a parameter, you can read its EntryID property.

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

    Tuesday, September 1, 2015 1:54 PM
  • Thanks very much, i have following code snippet to handle item change event.

    void __stdcall CAddin::OnItemChange(IDispatch * item)

    Here i can convert IDispatch to Outlook::_MailItem

    CComQIPtr<Outlook::_MailItem> spMailItem

    i want an  IProxyStoreObject  so that, it should not sync with server.

    How can i do this?

    you reply can help me a lot.


    Wednesday, September 2, 2015 6:38 AM
  • How can i obtain lpMDBIn in my code.

    As per below code:

    HRESULT HrUnWrapMDB(LPMDB lpMDBIn, LPMDB* lppMDBOut) { HRESULT hRes = S_OK; IProxyStoreObject* lpProxyObj = NULL; LPMDB lpUnwrappedMDB = NULL; hRes = lpMDBIn->QueryInterface(IID_IProxyStoreObject,(void**)&lpProxyObj); if (SUCCEEDED(hRes) && lpProxyObj) { hRes = lpProxyObj->UnwrapNoRef((LPVOID*)&lpUnwrappedMDB); if (SUCCEEDED(hRes) && lpUnwrappedMDB) { // UnwrapNoRef doesn't addref, so do it here lpUnwrappedMDB->AddRef(); (*lppMDBOut) = lpUnwrappedMDB; } } if (lpProxyObj) lpProxyObj->Release(); return hRes; }

    Wednesday, September 2, 2015 11:06 AM
  • This topic shows a code sample in C++ that queries a message store for the IProxyStoreObject interface.

    Its an IMsgStore interface pointer that you should obtain from the Outlook Store object.

    • Marked as answer by rsquareshelke Monday, September 7, 2015 8:25 AM
    Wednesday, September 2, 2015 11:32 AM
  • Thanks RLWA32.

    Actually you helped me a lot :)

    Wednesday, September 2, 2015 12:34 PM
  • You can retrieve it from Store.MAPIOBJECT in the Outlook Object Model.

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

    • Marked as answer by rsquareshelke Monday, September 7, 2015 8:25 AM
    Wednesday, September 2, 2015 3:01 PM
  • Thanks Dmitry Streblechenko _MVP

    let me try to implement same..

    i do not want to the changed content in mail which will sync with server

    many thanks.

    Thursday, September 3, 2015 6:48 AM