VSTO: обработайте почту с помощью newmailex перед почтой перемещения правил перспективы

Я создаю дополнение для Outlook 2007, который читает почтовый объект, когда он получен и затем переписывает его. Дополнение работает отлично и переписывает почту для объектов, которые не имеют правила Outlook, которое перемещает их в другую папку. Если существует правило, оно прекрасно все еще приблизительно 50% времени. Другие 50% времени, правило перемещает почтовый объект, прежде чем мое дополнение закончится. Я получаю следующую ошибку:

"Операция не может быть выполнена, потому что объект был удален".

Я использую событие NewMailEx для вызывания моей функции перезаписи:

private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
    this.Application.NewMailEx += new Outlook.ApplicationEvents_11_NewMailExEventHandler(olApp_NewMail);
}

В Outlook 2007 NewMailEx дает entryID для почты. Этот entryID используется первоначально для выяснения, какой почте возражают для использования:

Outlook.NameSpace outlookNS = this.Application.GetNamespace("MAPI");
Outlook.MAPIFolder mFolder = this.Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
Outlook.MailItem mail;
try
{
    mail = (Outlook.MailItem)outlookNS.GetItemFromID(entryIDCollection, Type.Missing);
}
catch (Exception e) { Debug.WriteLine("exception with non-mail item " + entryIDCollection + ": " + e.ToString()); return; }

Я думал, что мог взять этот entryID (который вышеупомянутый код работает), и выполните итерации через все мои папки (на обмене, а также на моем компьютере) поиска того же почтового ID. Когда я наконец выполняю итерации туда, где почта, EntryID перемещенной почты очень отличается от entryIDCollection.

Возможно, я иду об этом неправильным путем. Кто-либо знает, как мешать событию распространить, пока я не сделан, или как разыскать перемещенную электронную почту?

Вот мой код для того, чтобы пересечь папки в случае, если чье-либо любопытное:

        try
        {
            mail.Subject = new_subj;
            mail.Body = "";
            mail.HTMLBody = text;
            mail.ClearConversationIndex();
            mail.Save();
        }
        catch (Exception ex)
        {
            //It wasn't caught in time, so we need to find the mail:
            ArrayList unreadFolders = new ArrayList();
            foreach (Outlook.Folder f in outlookNS.Folders) unreadFolders.Add(f);

            while (unreadFolders.Count > 0)
            {
                Outlook.Folder currentFolder = unreadFolders[0] as Outlook.Folder;
                Debug.WriteLine("reading folder: " + currentFolder.Name);
                unreadFolders.RemoveAt(0);


                foreach (Outlook.Folder f in currentFolder.Folders) unreadFolders.Add(f);

                try
                { 
                    Outlook.Items items = currentFolder.Items.Restrict("[UnRead] = true");
                    for (int itemNum = 1; itemNum <= items.Count; itemNum++)
                    {
                        if (!(items[itemNum] is Outlook.MailItem)) continue;
                        Outlook.MailItem m = items[itemNum];
                        if (m.EntryID == entryIDCollection)
                        {
                            m.Subject = new_subj;
                            m.Body = "";
                            m.HTMLBody = text;

                            m.ClearConversationIndex();
                            m.Save();
                            return;
                        }

                    }
                }
                catch (Exception exc) { }
            }

        }
8
задан casperOne 10 May 2012 в 12:42
поделиться

2 ответа

Непроверенная идея : Если вы надежно получаете событие NewMailEx, пометьте почту свойством пользователя или пробегом с GUID, а затем используйте поиск для этого.

Это может не сработать, так как вы можете не успеть войти до того, как Правило переместит почту.

Как вы уже поняли, EntryId меняется, когда элемент перемещается.

Другим способом вам нужно посмотреть на реквизиты MAPI, чтобы получить PR_SEARCH_KEY, который не меняется при перемещении почты.

5
ответ дан 5 December 2019 в 17:36
поделиться

Ответ 76mel сработал отлично! Я публикую свой получившийся код на тот случай, если другие захотят сделать что-то подобное (я новичок и не уверен в правилах публикации большого количества кода, извините, если это противоречит правилам):

private string getPRSearchKey(Outlook.MailItem m)
{
    return m.PropertyAccessor.BinaryToString(m.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x300B0102"));
}

private void olApp_NewMail(string entryIDCollection)
{
    Outlook.NameSpace outlookNS = this.Application.GetNamespace("MAPI");
    Outlook.MAPIFolder mFolder = this.Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
    Outlook.MailItem mail;

    string pr_search_key;
    string old_subj;
    string old_body;
    try
    {
        mail = (Outlook.MailItem)outlookNS.GetItemFromID(entryIDCollection, Type.Missing);
        pr_search_key = getPRSearchKey(mail);
        //save the pr_search_key, subject, and body before the mailItem gets moved
        // then we can work on it without worrying about them disappearing
        old_subj = mail.Subject;
        old_body = mail.Body;
    }
    catch (Exception e) { Debug.WriteLine("exception with non-mail item " + entryIDCollection + ": " + e.ToString()); return; }

    //
    // ... do stuff with the mail's body and subject
    //

    try
    {
        mail.Subject = new_subj;
        mail.Body = "";
        mail.HTMLBody = text;

        mail.ClearConversationIndex();
        mail.Save();
    }
    catch (Exception ex)
    {
        //It wasn't caught in time, so we need to find the mail:
        ArrayList unreadFolders = new ArrayList();
        foreach (Outlook.Folder f in outlookNS.Folders) unreadFolders.Add(f);

        while (unreadFolders.Count > 0)
        {
            Outlook.Folder currentFolder = unreadFolders[unreadFolders.Count-1] as Outlook.Folder;
            Debug.WriteLine("reading folder: " + currentFolder.Name);
            unreadFolders.RemoveAt(unreadFolders.Count - 1);


            foreach (Outlook.Folder f in currentFolder.Folders) unreadFolders.Add(f);

            try
            { 
                Outlook.Items items = currentFolder.Items.Restrict("[UnRead] = true");
                for (int itemNum = 1; itemNum <= items.Count; itemNum++)
                {
                    if (!(items[itemNum] is Outlook.MailItem)) continue;
                    Outlook.MailItem m = items[itemNum];
                    if (getPRSearchKey(m) == pr_search_key)
                    {
                        m.Subject = new_subj;
                        m.Body = "";
                        m.HTMLBody = text;

                        m.ClearConversationIndex(); //don't think this works
                        m.Save();
                        return;
                    }

                }
            }
            catch (Exception exc) { }
        }

    }
}

кстати, кое-что, что я сделаю возможно изменение в том, что я пропущу запросы к определенным папкам, чтобы немного ускорить его (Журнал, Удаленные элементы, Нежелательная почта, Черновики, RSS-каналы, Microsoft at Home, Задачи, Заметки, Контакты, Календарь, Отправленные, Исходящие).

5
ответ дан 5 December 2019 в 17:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: