Outlook 2016 mapi.MAPIUninitialize() 崩溃

Posted

技术标签:

【中文标题】Outlook 2016 mapi.MAPIUninitialize() 崩溃【英文标题】:Outlook 2016 mapi.MAPIUninitialize() crashes 【发布时间】:2015-12-01 05:46:36 【问题描述】:

在我的多线程应用程序中,多个线程通过映射初始化

mapi.MAPIInitialize((0, mapi.MAPI_MULTITHREAD_NOTIFICATIONS))

mapi.MAPIUninitialize() crashes. I got the following call stack from windbg.

mso30win32client!Ordinal250+0x32423    
mso30win32client!Ordinal126+0x5b   
mso30win32client!Ordinal1337+0x39d   
mso30win32client!Ordinal1470+0x17e    
mso30win32client!Ordinal1470+0xe    
mso40uiwin32client!Ordinal2408+0x19    
olmapi32!LINKEDLIST_RemoveKey+0x4e6   
olmapi32!HrUninitMso+0x36    
olmapi32!MAPIUninitialize+0x9    
MSMAPI32!MAPIUninitialize+0x42   
MAPI32!MAPIUninitialize+0x5b    
mapi+0x11d9    

每个线程仅按顺序执行以下 mapi(Outlook 2016) 调用: 1 MAPII初始化 2 MAPIAdminProfiles 3 HrQueryAllRows 4 会话=MAPILogonEx 5 会话.注销 6 MAPIUninitialize

观察: 如果有两个线程 T1 和 T2 . T1 在 T2 之前登录到会话,并且 T1 在 T2 之后执行 MAPIUninitialize 它不会导致崩溃, 但是,如果 T1 在 T2 之前登录会话,并且 T1 在 T2 之前执行 MAPIUninitialize,则调用 MAPIUninitialize 会导致上述堆栈崩溃。

在 Outlook 2016 中出现崩溃,仅适用于 Outlook 2013 及更低版本。

【问题讨论】:

我有类似的错误,但使用 Access OLEDB 引擎(Office Access 2016 的一部分),-***.com/questions/37432816/… 尝试更新到 Office 最新版本。 【参考方案1】:

T1 用在主线程上,T2 用在辅助线程上吗?

查看MAPI Multithreading Rules 页面,该页面声明如下:

如果不使用 MAPI_MULTITHREAD_NOTIFICATIONS,第一个调用 MAPIInitialize 的线程应该比所有其他 MAPI 线程的寿命更长,并且应该是最后一个调用 MAPIUninitialize 的线程。

看起来提到的标志现在没有任何作用,您应该保留调用顺序,即使用 LIFO(后进先出)。

【讨论】:

这里 T1 和 T2 是同级级别的线程,由一个线程说 M 创建。线程 M 不执行任何 mapi 调用因此我没有为线程 M 执行 mapi.MAPIInitialize 和 mapi.MAPIUninitialize。是这可能是问题吗?【参考方案2】:

确保在 T1 和 T2 启动之前在主线程上调用 MAPIInitialize,并在两个线程退出后调用 MAPIUninitialize。

【讨论】:

是否必须在 Outlook 2016 的主线程上调用 MAPIInitialize 和 MAPIUninitialize,因为它适用于 Outlook 2013 和更早版本。在 T1 和 T2 启动之前在主线程上进行 MAPIIinitialize 并在两个线程退出后进行 MAPIUninitialize 失败。但是,如果我在 T1 和 T2 启动之前在主线程上调用 MAPIInitialize , MAPILogonEx 并在两个线程退出后注销和 MAPIUninitialize 它工作正常是否与主线程有任何关系。 是的。 MAPI 系统将调用 MAPIInitialize 的第一个线程视为创建具有线程关联性(窗口句柄等)的事物的主线程。如果 MAPI 认为的主线程被杀死,而另一个线程仍在使用 MAPI,那么肯定会发生不好的事情。这不是 2016 年特定的。你以前运气不错。 1.T1 和T2 启动前主线程上的MAPIIinitialize 和两个线程退出后主线程上的MAPIUninitialize 也会导致崩溃。仅当我在 T1 和 T2 启动之前在主线程上调用 MAPIInitialize 时,MAPILogonEx 并且在两个线程退出后注销和 MAPIUninitialize 工作正常 2.即使 MAPI_MULTITHREAD_NOTIFICATIONS 标志为所有线程在 MAPIInitialize 中传递,第一个调用 MAPIInitialize 的线程被认为是MAPI 系统成为主线程? 需要通过为每个活动生成线程来处理多个活动请求。由于没有每个线程启动和退出的顺序因此我正在为每个线程执行 MAPIIinitialize、MAPILogonEx 和 Logoff、MAPIUninitialize。有可能只有一个线程启动并执行 MAPIIinitialize 、MAPILogonEx 和 Logoff 、MAPIUninitialize 并退出 或者多个线程并行启动执行 MAPIIinitialize 、MAPILogonEx 和 Logoff 、MAPIUninitialize ,每个线程都在自己的上下文中并以某种随机顺序退出。 IMAPISession 可以在多个线程之间共享。在主线程上调用 MAPIInitialize / MAPILogonEx。生成辅助线程,在每个线程上调用 MAPIInitialize 并从主线程使用 IMAPISession。

以上是关于Outlook 2016 mapi.MAPIUninitialize() 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

Outlook 2016 Bug / 尚未发布补丁修正

outlook2016版无法突破邮件附件大小上限

Outlook 2016 mapi.MAPIUninitialize() 崩溃

Exchange 2016 客户端外网环境无法使用outlook2013/2016连接故障

如何解除 outlook 2016 附件大小的限制

备份和导入Outlook 2016 电子邮件签名