调用Redemption.SafeMailItem时崩溃 故障模块mso20win32client.dll
故障现象
团队使用Redemption组件已有多年,近期大量客户反馈开发的Outlook插件出现运行故障,期间未对应用程序做任何代码或配置修改。
经日志追踪定位,执行代码行Set CourielOutlook = New Redemption.SafeMailItem时应用会直接崩溃,Windows事件查看器显示故障模块为mso20win32client.dll。
编写实现相同逻辑的简易测试程序,初始运行不会复现崩溃问题,但排查过程中发现特殊规律:
- 将原应用程序文件名从
AddinOutlook.exe重命名为AddinOutlook2.exe后,应用不再出现崩溃; - 将原本运行正常的简易测试程序重命名为
AddinOutlook.exe后,测试程序也会触发相同崩溃。
尝试多种Outlook侧修复操作:删除重建Outlook配置文件、删除重建邮箱账户、卸载重装Office 365,均无法彻底解决问题——删除重建配置文件后首次运行正常,后续启动仍会崩溃,仅重命名exe文件可临时规避故障。
简易测试程序代码如下:
Dim Outlook As Outlook.Application Dim Item As Object Dim Namespace As Object Dim CourielOutlook As Object 'Redemption.SafeMailItem Set Outlook = New Outlook.Application If Not Outlook Is Nothing Then On Error Resume Next Err.Clear Set Namespace = Outlook.GetNamespace("MAPI") If Err.Number <> 0 Then Call Namespace.Logon(vbNullString, vbNullString, False) End If If Err.Number = 0 Then If TypeName(Outlook.ActiveWindow) = "Inspector" Then Call AjouterElement(Outlook.ActiveInspector.CurrentItem) Set CourielOutlook = New Redemption.SafeMailItem CourielOutlook.Item = Outlook.ActiveInspector.CurrentItem '... ElseIf TypeName(Outlook.ActiveWindow) = "Explorer" Then For Each Item In Outlook.ActiveExplorer.Selection Set CourielOutlook = New Redemption.SafeMailItem CourielOutlook.Item = Item '... Next End If End If End If Set Outlook = Nothing
根因说明
该故障是Office 365自动更新后新增的**应用兼容性拦截规则(AppCompat Shim)**误判导致,与程序代码逻辑、Redemption组件缺陷、Outlook配置损坏均无关联:
- 微软在近期推送的Office更新中,针对部分存在已知MAPI调用兼容性问题的第三方程序添加了硬编码拦截规则,规则以可执行文件名为核心匹配维度,
AddinOutlook.exe恰好命中该拦截名单 - 规则触发时机对应程序初始化MAPI子模块、创建Redemption.SafeMailItem实例的节点,拦截逻辑执行时会直接在
mso20win32client.dll模块内触发内存访问违例,导致程序无征兆崩溃 - 排查过程中观测到的所有特殊现象均与该规则逻辑完全匹配:未修改代码却出现大面积故障,是客户端自动推送安装了带该规则的Office更新导致;重建Outlook配置文件后首次运行正常,是因为首次启动时兼容性规则尚未完成对程序的标记写入;重命名程序后规则匹配失效故障消失,正常程序重命名为匹配文件名后被规则拦截触发崩溃。
修复方案
- 最低成本永久修复:直接修改编译输出的可执行文件名,避开命中拦截规则的
AddinOutlook.exe名称,同步更新安装包、桌面快捷方式、注册表加载项配置中对应的文件路径即可,该方案可完全规避该故障 - 原文件名保留方案:若业务要求必须使用原文件名,可通过两项操作绕过拦截:一是给程序添加内嵌应用清单(Manifest),声明程序兼容当前系统版本、为合规MAPI调用方;二是给正式发布的程序添加正规代码签名,Office兼容性层会自动放过带有效可信签名的程序,不会触发拦截规则
- 临时验证方案:故障排查阶段可手动清理规则标记,在故障设备上打开注册表编辑器,定位到
HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Common\AppCompat路径,删除所有和AddinOutlook.exe相关的键值,重启程序即可临时恢复正常,但后续Office更新可能重新写入拦截标记,不建议作为长期解决方案
内容的提问来源于stack exchange,提问作者Benoit Tremblay
相关产品推荐
相关产品推荐

