如何在Outlook PIA实现中处理应用程序生存期

时间:2015-12-08 14:16:38

标签: c# outlook office-interop office-pia

问题陈述

当Outlook退出时,任何通过PIA注册的事件都将丢失,并且当前在内存中的任何PIA对象都将无法访问。

重现

这是一个简单的控制台应用程序,用于说明手头的问题:

static void Main(string[] args)
{
    var outlookApp = new Application();
    var ns = outlookApp.GetNamespace("MAPI");
    var calendar = ns.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
    var appointment = (AppointmentItem) calendar.Items.GetFirst();

    ((ApplicationEvents_11_Event) outlookApp).Quit +=
        () => Console.WriteLine("Outlook is quitting");

    while (true)
    {
        Console.WriteLine("Explorers: " + outlookApp.Explorers.Count);
        Console.WriteLine("Folders: " + ns.Folders.Count);
        Console.WriteLine("Items: " + calendar.Items.Count);
        Console.WriteLine("Start date: " + appointment.Start);
        Thread.Sleep(2000);
    }
}

当我运行此应用程序时,如果Outlook尚未运行,它将在单独的进程(如系统托盘中显示)中启动Outlook实例。我知道有三种情况会导致Quit事件触发:

  1. Outlook处于"隐藏"状态,然后从系统任务栏图标的上下文菜单中选择立即退出退出。
  2. Outlook已在应用程序启动时运行,并且用户关闭或退出正在运行的资源管理器。
  3. 应用程序启动时Outlook未运行,因此在"隐藏"状态,然后用户通过运行可执行文件或从系统任务栏图标的上下文菜单中选择打开Outlook 来启动Outlook应用程序。然后用户关闭或退出正在运行的资源管理器。
  4. 其中每个对我的程序都有相同的效果:Quit事件被触发,然后我尝试访问Outlook对象失败了COMException

    问题

    处理此问题的标准或推荐方法是什么?从理论上讲,应用程序退出可以随时异步发生。我是否需要在使用PIA的任何操作上捕获COMException并在发生异常时从调用new Application()重新启动操作?这可能很棘手,具体取决于操作的复杂程度。

    事件处理程序怎么样?我是否需要跟踪已添加到Outlook对象的所有事件处理程序,然后在收到Application.Quit事件时重新添加它们?

    用户体验怎么样?假设用户从系统托盘的上下文菜单中选择立即退出,然后图标立即重新出现,因为我的应用程序检测到退出并重新初始化所有内容。我是否应该向用户弹出某种对话框,通知他们我的应用程序需要Outlook才能正常运行?

    在系统关闭情况下怎么办?据推测,在我从Outlook收到SystemEvents.SessionEnding之前,我会收到一个Application.Quit事件。这是保证,还是我应该等待一段时间才能恢复通信,看看系统是否正在停止运行?还有其他方法可以检测我们是否处于会话结束状态吗?

    为多方面问题道歉。如果有一篇文章已经涉及该主题,欢迎阅读材料链接。经过大量的搜索,我找不到一个。

1 个答案:

答案 0 :(得分:0)

如果Application.Quit没有触发,你可以挂钩Explorer.Close和Inspector.Close事件并检查Aplication.Explorers.Count和Aplication.Inspectors.Count是否都为0(或者自你处理的事件以来还是1)窗户打开了。)

要连接这些事件,请跟踪Application.Explorers.NewExplorer和Application.Inspectors.NewInspector事件。要连接Outlook已显示的资源管理器和检查器,请在启动时循环访问Application.Explorers和Application.Inspectors集合。