如何监控Outlook中所有本地邮箱文件夹的新邮件事件?

问题描述 投票:0回答:1

我开发了一个vsto插件。每次运行 Outlook 时,我都需要向本地邮箱中的所有文件夹添加新邮件事件。我期望的是,当邮箱文件夹同步新邮件以获取新邮件信息时,会触发此事件。

_application = Application;

_nameSpace = Application.GetNamespace("MAPI");

_application.NewMailEx += new Outlook.ApplicationEvents_11_NewMailExEventHandler(ItemAdd);

我尝试了此代码,但只有当收件箱文件夹中收到新电子邮件时才会触发 NewMailEx 事件。

private void ThisAddInStartup(object sender, System.EventArgs e)
        {
_dataFiles = Application.GetNamespace("MAPI").Folders;

var subFolders = _dataFiles.Cast<Outlook.Folder>()
                           .Where(dataFile => IsEmailFormat(dataFile.Name))
                           .SelectMany(dataFile => dataFile.Folders.Cast<Outlook.Folder>()).ToList();

subFolders.ForEach(async x =>
{
    await RecursionAsync(x);
});
}

 public async Task RecursionAsync(Outlook.Folder folder)
        {
            if (!IsExcludedFolder(folder.Name))
            {
                folder.Items.ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(ItemAdd);
                var restriction = $"[ReceivedTime] >= '{DateTime.Now.AddDays(-1):g}'";

                Outlook.Items filteredItems = folder.Items.Restrict(restriction);

                if (filteredItems.Count > 0)
                {
                    foreach (Outlook.MailItem mailItem in filteredItems)
                    {
                        await _translateClient.OutlookTranslateTaskAsync(GetNeedToTranslatedContent(mailItem.HTMLBody), TranslationLanguage.ZhTw, mailItem.EntryID, _cancellationToken).ConfigureAwait(false);
                    }
                }

                if (folder?.Folders.Count > 0)
                    foreach (Outlook.Folder subFolder in folder.Folders) await RecursionAsync(subFolder);
            }
        }

我也尝试过此代码,但在使用 Outlook 时,ItemAdd 事件阻止了此事件的触发

outlook vsto
1个回答
0
投票

COM 对象触发事件 (

Items
) - 必须保持活动状态才能触发事件。
folder.Items.ItemAdd += ...
行在临时变量(
folder.Items
)上设置了一个事件处理程序,当它超出范围并且垃圾收集器释放它时,该变量将被释放。它必须在火灾事件中保持活力。创建一个包装类,将
Folder
作为参数,并将其及其
Items
集合存储为类成员 (
_items = folder.Items;
)。在指向包装类方法的该成员上设置事件处理程序 (
_items.ItemAdd += SomeHandler;
)。将包装类存储在列表中以使其保持活动状态。

话虽如此,在数百或数千个文件夹上设置事件处理程序是一个非常糟糕的主意。在在线(无 OST)模式下肯定会失败。事件可以用作同步必须尽快发生而不是稍后发生的提示,但不应将其用作唯一的触发器。

© www.soinside.com 2019 - 2024. All rights reserved.