0

我正在使用 C# 和 Visual Studio 2010 开发我的第一个 Outlook 2010 插件。到目前为止,我的项目进展顺利。我在功能区中有一个自定义选项卡,每次在 Outlook 窗口中选择新消息时它都会更新。分析电子邮件中的文本,并在功能区中显示不同的信息。

使这一切工作的原因在于我的 ThisAddIn_Startup 方法。在那里我绑定了一些 Outlook 事件,因此我的代码可以在选择新电子邮件时做出相应的反应。

真正令人不安的是,大约有 1/3 的时间间歇性地失败。我们公司有多个来自不同供应商的 Outlook 加载项,因此很难确切知道 Outlook 启动过程中发生了什么。有时我的代码绑定到 Outlook 的事件,有时没有。如果没有,我关闭并重新打开 Outlook,它就可以工作了。任何意见,将不胜感激。有没有更好的方法可以使这项工作?如果我必须预料到这些间歇性启动失败,有什么想法可以让我的加载项意识到这一点并在不需要重新启动应用程序的情况下恢复?

这是我在 ThisAddIn.cs 中的代码示例:

private void ThisAddIn_Startup(object sender, System.EventArgs e) {
    // set up event handler to catch when a new explorer (message browser) is instantiated
    Application.Explorers.NewExplorer += new Microsoft.Office.Interop.Outlook.ExplorersEvents_NewExplorerEventHandler(NewExplorerEventHandler);

    // ...and catch any Explorers already existing before this startup event was fired
    foreach (Outlook.Explorer Exp in Application.Explorers) {
        NewExplorerEventHandler(Exp);
    }
}

public void NewExplorerEventHandler(Microsoft.Office.Interop.Outlook.Explorer Explorer) {
    if (Explorer != null) {
        //set up event handler so our add-in can respond when a new item is selected in the Outlook explorer window
        Explorer.SelectionChange += new Outlook.ExplorerEvents_10_SelectionChangeEventHandler(ExplorerSelectionChange);
    }
}

private void ExplorerSelectionChange() {
    Outlook.Explorer ActiveExplorer = this.Application.ActiveExplorer();
    if (ActiveExplorer == null) { return; }
    Outlook.Selection selection = ActiveExplorer.Selection;
    Ribbon1 ThisAddInRibbon = Globals.Ribbons[ActiveExplorer].Ribbon1;

    if (ThisAddInRibbon != null) {
        if (selection != null && selection.Count == 1 && selection[1] is Outlook.MailItem) {
            // one Mail object is selected
            Outlook.MailItem selectedMail = selection[1] as Outlook.MailItem; // (collection is 1-indexed)
            // tell the ribbon what our currently selected email is by setting this custom property, and run code against it
            ThisAddInRibbon.CurrentEmail = selectedMail;
        } else {
            ThisAddInRibbon.CurrentEmail = null;
        }
    }
}

更新:我在 ThisAddIn 类中添加了两个变量,用于两个我想从中捕获事件的对象:

Outlook.Explorers _explorers; // used for NewExplorerEventHandler
Outlook.Explorer _activeExplorer; // used for ExplorerSelectionChange event

在 ThisAddIn_Startup 中:

_explorers = Application.Explorers;
_explorers.NewExplorer += new Microsoft.Office.Interop.Outlook.ExplorersEvents_NewExplorerEventHandler(NewExplorerEventHandler);

在 ExplorerSelectionChange 中:

_activeExplorer = this.Application.ActiveExplorer();
4

1 回答 1

3

使用 COM 对象时:当您想要订阅一个事件时,您必须在类/应用程序级别保留对该对象的引用,否则当超出范围时它将被垃圾收集。

于 2013-01-17T13:46:56.240 回答