Shary Uladzimir Shary Uladzimir - 3 days ago 6
C# Question

How to save MailItem after sending

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);
}
}

Answer

use Items.ItemAdd event on the Sent Items folder.

Comments