-1

I'am creating MailItem:

    Application outlook = new Application();
    _mailItem = outlook.CreateItem(OIItemType.olMailItem);                
    Inspector inspector = _mailItem .GetInspector;
    inspector.Activate();     

set recipient, body, etc... Subscribe to an send event:

    ((ItemEvents_10_Event)_mailItem).Send += MailItemSendHandler;

    void MailItemSendHandler(ref bool isSended) {
        _mailItem.SaveAs(filePath);
    }

When a user sent the email, I save it. But my email saved in compose mode. If i will open it in OutLook, i can change all information and i can resend it.

If i subscribe to the MailItem Inspector close event:

 ((InsPectorsEvents_10_Event)inspector).Close += CloseEventHandler;

and saving MailItem in CloseEventHandler, i have an error:

"Item has been moved or deleted".

How can i save my MailItem after it will be sended and moved in "Sent items" Outlook folder? (save in read mode)

EDIT

I'am using Items.AddItem event for saving my sent _mailItem. Get folder:

_sentFolderItems = _mailItem.SaveSentMessageFolder;

subscribe with some logic in _addEventHandler:

_sentFolderItems.Items.ItemAdd += _addEventHandler;

Good:

  1. Outlook main window is running.
  2. Outlook process is displayed in task manager.
  3. I'am generating MailItem, showing it for user. User make some changes if he wish, and press send button.
    4. Items.ItemAdd is fired and _addEventHandler is executed.
  4. Outlook mail window is still running, and outlook process is displayed in task manager.

Bad:

Outlook main window is not running, and there is no process in task manager. I'am generating MailItem, show it for user. There is only window for sending email displayed for user. Outlook process is displayed in task manager. User make some changes if he wish, and press send button. Mail is sended and task Manager does'nt have a OutLook process. Items.ItemAdd is NOT fired and _addEventHandler is NOT executed. But of corse sent item is located in sent folder.

 public class MailItemWrapper {
    public MailItemWrapper(MailItem mailItem, ComposeEmailWrapper composeEmailWrapper, bool isCompose) {
        _mailItem = mailItem;
        _identifyProperty = Guid.NewGuid();
        _mailItem.AddUserProperty(_identifyProperty.ToString(), _identifyProperty.ToString());
        _sentFolderItems = _mailItem.SaveSentMessageFolder;
        _inspector = _mailItem.GetInspector;
        _composeEmailWrapper = composeEmailWrapper;
        InComposeMode = isCompose;
        SetEventHandlers();
        Subscribe();
        _isSending = false;
    }

    private MailItem _mailItem;
    private Inspector _inspector;
    private MAPIFolder _sentFolderItems;
    private InspectorEvents_10_CloseEventHandler _closeEventHandler;
    private ItemEvents_10_SendEventHandler _sendEventHandler;
    private ItemsEvents_ItemAddEventHandler _addEventHandler;
    private readonly ComposeEmailWrapper _composeEmailWrapper;
    private string _path;
    private bool _isSending;
    private Guid _identifyProperty;

    public bool InComposeMode {
        get; set;
    }

    public MailItem MailItem {
        get {
            return _mailItem;
        }
    }

    public void Subscribe() {
        ((ItemEvents_10_Event) _mailItem).Send += _sendEventHandler;
        ((InspectorEvents_10_Event) _inspector).Close += _closeEventHandler;
        _sentFolderItems.Items.ItemAdd += _addEventHandler;
    }

    public void UnsubscribeAndRelease() {
        if(InComposeMode) {
            ((ItemEvents_10_Event) _mailItem).Send -= _sendEventHandler;
            ((InspectorEvents_10_Event) _inspector).Close -= _closeEventHandler;
            _sentFolderItems.Items.ItemAdd -= _addEventHandler;

            Marshal.ReleaseComObject(_sentFolderItems);
            Marshal.ReleaseComObject(_mailItem);
            Marshal.ReleaseComObject(_inspector);

            _sentFolderItems = null;
            _mailItem = null;
            _inspector = null;
            InComposeMode = false;
            _isSending = false;
        }
    }

    private void SetEventHandlers() {
        _sendEventHandler = (ref bool cancel) =>{           
            _isSending = true;
        };

        _addEventHandler = delegate (object item) {
            var mailItem = item as MailItem;
            if(mailItem != null) {
                var identityer = mailItem.UserProperties.Find(_identifyProperty.ToString());
                if(identityer != null && _identifyProperty.ToString() == identityer.Value) {
                    _path = mailItem.SaveAsInTempFolder(); // extension
                    if(_composeEmailWrapper != null && _composeEmailWrapper.Callback != null) {
                        System.Windows.Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (System.Action) ExecuteCallBack);
                        UnsubscribeAndRelease();
                    }
                }
                Marshal.ReleaseComObject(mailItem);
            }

        };

        _closeEventHandler = () => {
            // if user close dialog without sending => unsibscribe
            if(!_isSending) {
                UnsubscribeAndRelease();
            }
        };
    }

    private void ExecuteCallBack() {
        _composeEmailWrapper.Callback(_path, _composeEmailWrapper.SessionId);
    }
}
Uladzimir Sharyi
  • 144
  • 1
  • 14
  • Not a direct answer, hence the comment. But if you use MS-SQL Server already you could look into DBMail. If you use DBMail all emails are saved in the database automatically. – Ryan Mann Nov 28 '16 at 16:30
  • @RyanMann, i am saving emails in the windows temp folder(on the client side), and then uploading them to the server. I think, that to use Outlook emails storage directly is not good idea. – Uladzimir Sharyi Nov 28 '16 at 17:32
  • Yeah I failed to realize this was an outlook api question. I thought it was a web app related question. – Ryan Mann Nov 29 '16 at 15:14

1 Answers1

0

use Items.ItemAdd event on the Sent Items folder.

Dmitry Streblechenko
  • 62,942
  • 4
  • 53
  • 78