Как сохранить MailItem после отправки

Я создаю MailItem:

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

установить получателя, тело и т. д. Подпишитесь на событие отправки:

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

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

Когда пользователь отправляет электронное письмо, я сохраняю его. Но моя электронная почта сохранена в режиме создания. Если я открою его в OutLook, я могу изменить всю информацию и отправить ее повторно.

Если я подпишусь на событие закрытия MailItem Inspector:

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

и сохраняю MailItem в CloseEventHandler, у меня ошибка:

"Item has been moved or deleted".

Как я могу сохранить свой MailItem после того, как он будет отправлен и перемещен в папку «Отправленные» Outlook? (сохранить в режиме чтения)

ИЗМЕНИТЬ

Я использую событие Items.AddItem для сохранения отправленного _mailItem. Получить папку:

_sentFolderItems = _mailItem.SaveSentMessageFolder;

подписаться с некоторой логикой в ​​_addEventHandler:

_sentFolderItems.Items.ItemAdd += _addEventHandler;

Хорошо:

  1. Главное окно Outlook запущено.
  2. Процесс Outlook отображается в диспетчере задач.
  3. Я создаю MailItem, показываю его пользователю. Пользователь вносит некоторые изменения, если хочет, и нажимает кнопку отправки.
    4. Запускается Items.ItemAdd и выполняется _addEventHandler.
  4. Почтовое окно Outlook все еще работает, а процесс Outlook отображается в диспетчере задач.

Плохой:

Главное окно Outlook не запущено, а в диспетчере задач нет процессов. Я создаю MailItem, показываю его пользователю. Для пользователя отображается только окно отправки электронной почты. Процесс Outlook отображается в диспетчере задач. Пользователь вносит некоторые изменения, если хочет, и нажимает кнопку отправки. Почта отправляется, а в диспетчере задач нет процесса OutLook. Items.ItemAdd НЕ запускается и _addEventHandler НЕ запускается. Но отправленный элемент находится в папке отправленных.

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

person Uladzimir Sharyi    schedule 28.11.2016    source источник
comment
Не прямой ответ, отсюда и комментарий. Но если вы уже используете MS-SQL Server, вы можете заглянуть в DBMail. Если вы используете DBMail, все электронные письма автоматически сохраняются в базе данных.   -  person Ryan Mann    schedule 28.11.2016
comment
@RyanMann, я сохраняю электронные письма во временной папке Windows (на стороне клиента), а затем загружаю их на сервер. Я думаю, что использовать хранилище электронной почты Outlook напрямую не очень хорошая идея.   -  person Uladzimir Sharyi    schedule 28.11.2016
comment
Да, я не понял, что это вопрос API Outlook. Я думал, что это вопрос, связанный с веб-приложением.   -  person Ryan Mann    schedule 29.11.2016


Ответы (1)


используйте событие Items.ItemAdd в папке "Отправленные".

person Dmitry Streblechenko    schedule 28.11.2016
comment
Спасибо за ответ, @DmitryStreblechenko. После этого я обнаружил проблему с аналогичной проблемой: Outlook">stackoverflow.com/questions/12515612/ - person Uladzimir Sharyi; 29.11.2016
comment
я использую MailItem.SaveSentMessageFolder для подписки. Но это событие не срабатывает, когда Outlook закрыт. - person Uladzimir Sharyi; 29.11.2016
comment
Я не совсем понимаю, что вы имеете ввиду. Пожалуйста, покажите свой код. - person Dmitry Streblechenko; 29.11.2016
comment
спасибо за помощь. Я отредактировал свой вопрос. Может будет понятнее. - person Uladzimir Sharyi; 30.11.2016
comment
Не сохраняйте _sentFolderItems как глобальную переменную/переменную класса. Сохранить _sentFolderItems.Items — объект, вызывающий события, должен быть живым. - person Dmitry Streblechenko; 30.11.2016