当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
事件触发:
其中每个对我的程序都有相同的效果:Quit
事件被触发,然后我尝试访问Outlook对象失败了COMException
。
处理此问题的标准或推荐方法是什么?从理论上讲,应用程序退出可以随时异步发生。我是否需要在使用PIA的任何操作上捕获COMException
并在发生异常时从调用new Application()
重新启动操作?这可能很棘手,具体取决于操作的复杂程度。
事件处理程序怎么样?我是否需要跟踪已添加到Outlook对象的所有事件处理程序,然后在收到Application.Quit
事件时重新添加它们?
用户体验怎么样?假设用户从系统托盘的上下文菜单中选择立即退出,然后图标立即重新出现,因为我的应用程序检测到退出并重新初始化所有内容。我是否应该向用户弹出某种对话框,通知他们我的应用程序需要Outlook才能正常运行?
在系统关闭情况下怎么办?据推测,在我从Outlook收到SystemEvents.SessionEnding
之前,我会收到一个Application.Quit
事件。这是保证,还是我应该等待一段时间才能恢复通信,看看系统是否正在停止运行?还有其他方法可以检测我们是否处于会话结束状态吗?
为多方面问题道歉。如果有一篇文章已经涉及该主题,欢迎阅读材料链接。经过大量的搜索,我找不到一个。
答案 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集合。