Событие ItemAdd не запускается для надстройки Outlook 2016

Я работаю над старой надстройкой Outlook, которая, похоже, не срабатывает при событии ItemAdd.

Это код прямо сейчас:

public partial class MyAddin
{
    private MAPIFolder sentItemsFolder;

    private void InternalStartup()
    {
        this.Startup += this.MyAddinStartup;
        this.Shutdown += this.MyAddinShutdown;
    }

    private void InboxFolderItemAdded(object item)
    {
        // Code that doesn't get executed
    }

    private void MyAddinShutdown(object sender, EventArgs e)
    {
        this.sentItemsFolder.Items.ItemAdd -= this.InboxFolderItemAdded;
        this.sentItemsFolder.ReleaseComObject();
        this.sentItemsFolder = null;
    }

    private void MyAddinStartup(object sender, EventArgs e)
    {
        using (var ns = this.Application.GetNamespace("MAPI").WithComCleanup())
        {
            this.sentItemsFolder = ns.Resource.GetDefaultFolder(OlDefaultFolder.oldFolderSentMail);
            this.sentItemsFolder.Items.ItemAdd += this.InboxFolderItemAdded;
        }
    }
}

При размещении точки останова в InboxFolderItemAdded() точка останова никогда не достигается. Я зашел достаточно далеко, чтобы заявить, что существует какая-то несовместимость с другой надстройкой, поскольку код работает, когда эта надстройка отключена. Проблема сейчас в том, что я недостаточно знаю, чтобы решить, в чем может быть проблема, можно ли каким-либо образом пометить объект SentItemsFolder как общий? В случае, если другая надстройка пытается получить эксклюзивный доступ (на самом деле не знаю, как это работает). У меня нет исходного кода надстройки, которая нарушает код.

Я предполагаю, что реальный вопрос заключается в следующем: как отлаживать проблемы несовместимости с другими надстройками или есть ли способ отредактировать код, который мне нужно обойти?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
25
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
this.sentItemsFolder.Items.ItemAdd -= this.InboxFolderItemAdded;

Определите исходный объект на уровне класса:

Outlook.Items items = null;

Затем в методе вы можете настроить его и подписаться на событие (я):

items = this.sentItemsFolder.Items;
items.ItemAdd -= this.InboxFolderItemAdded;

Итак, в основном вам нужно объявить исходный объект Items на уровне класса, чтобы предотвратить его считывание сборщиком мусора.

То же самое относится к циклу, в котором вы подписываетесь на события Items:

    private void MyAddinStartup(object sender, EventArgs e)
    {
        using (var ns = this.Application.GetNamespace("MAPI").WithComCleanup())
        {
            this.sentItemsFolder = ns.Resource.GetDefaultFolder(OlDefaultFolder.oldFolderSentMail);
            this.sentItemsFolder.Items.ItemAdd += this.InboxFolderItemAdded;
        }
    }

Вы можете определить список объектов Outlook.Items, где вы можете хранить исходные объекты:

List<Outlook.Items> items = new List<Outlook.Items>();

private void MyAddinStartup(object sender, EventArgs e)
{
    using (var ns = this.Application.GetNamespace("MAPI").WithComCleanup())
    {
        this.sentItemsFolder = ns.Resource.GetDefaultFolder(OlDefaultFolder.oldFolderSentMail);
        Outlook.Items itemsObject = this.sentItemsFolder.Items;        
        itemsObject.ItemAdd += this.InboxFolderItemAdded;
        // add to the list to prevent GC from swiping it out
        items.Add(itemsObject);
    }
}

Это сработало! Я читал об объявлении на уровне класса, но думал, что уже сделал это с MAPIFolder sentItemsFolder. Не могли бы вы объяснить, почему sentItemsFolder.Items оказался в GC, хотя sentItemsFolder объявлен на уровне класса?

AmazingRealist 05.04.2022 08:23

Это связано с тем, что свойство Items возвращает объект, который висит в памяти до тех пор, пока метод не будет выполнен. Когда это будет сделано, объект будет помечен для просмотра GC.

Eugene Astafiev 05.04.2022 09:01

Другие вопросы по теме