ItemAdd 事件未触发 Outlook 2016 加载项

ItemAdd event not firing for Outlook 2016 Add-in

我正在处理一个旧的 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 对象标记为以任何方式共享?以防其他加载项尝试独占访问(不知道这是如何工作的)。我没有破坏代码的加载项的源代码。

我想真正的问题是:如何调试与其他加载项的不兼容问题,或者有什么方法可以编辑我必须绕过它的代码?

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

在class级别定义源对象:

Outlook.Items items = null;

然后在方法中您可以设置它并订阅事件:

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

所以,基本上你需要在class级别声明源Items对象,以防止它被GC刷掉。

这同样适用于您订阅 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);
    }
}