【发布时间】:2022-08-22 16:05:22
【问题描述】:
语境
大约一个月以来,我的 Outlook 插件在使用 C#PropertyPageSite 对象更改属性时突然开始崩溃。当属性页中的文本字段发生更改并调用PropertyPageSite 对象的OnStatusChange 函数时会发生这种情况。
我将 Outlook 降级到 2021 的版本并且没有发生崩溃,这很可能意味着由于 Outlook 中的更新而出现问题。
我得到的错误如下
System.AccessViolationException
HResult=0x80004003
Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Source=<Cannot evaluate the exception source>
StackTrace:
<Cannot evaluate the exception stack trace>
我第一次注意到错误是在 Outlook 版本 2205 上。应用程序本身自上次运行以来没有改变。
代码
以下代码很重要。
OptionPage 类是这样声明的
public partial class OptionPage : UserControl, Outlook.PropertyPage {
...
}
从外部源为PropertyPageSite 和属性本身注册一个加载事件。
public OptionPage()
{
InitializeComponent();
// Register for the Load event.
this.Load += new EventHandler(OptionPage_Load);
}
加载事件的事件处理程序
void OptionPage_Load(object sender, EventArgs e)
{
// Load our Settings here
LoadOptions();
// Get our Parent PropertyPageSite Object and store it into Classvariable.
_PropertyPageSite = GetPropertyPageSite();
}
我抓取PropertyPageSite 对象的方式似乎得到了许多论坛帖子的建议。但是,据我所知,除了使用 Visual Basic 时,Microsoft 没有任何关于如何获取该对象的信息。
Outlook.PropertyPageSite GetPropertyPageSite()
{
Type type = typeof(System.Object);
string assembly = type.Assembly.CodeBase.Replace(\"mscorlib.dll\", \"System.Windows.Forms.dll\");
assembly = assembly.Replace(\"file:///\", \"\");
string assemblyName = System.Reflection.AssemblyName.GetAssemblyName(assembly).FullName;
Type unsafeNativeMethods = Type.GetType(System.Reflection.Assembly.CreateQualifiedName(assemblyName, \"System.Windows.Forms.UnsafeNativeMethods\"));
Type oleObj = unsafeNativeMethods.GetNestedType(\"IOleObject\");
System.Reflection.MethodInfo methodInfo = oleObj.GetMethod(\"GetClientSite\");
object propertyPageSite = methodInfo.Invoke(this, null);
return (Outlook.PropertyPageSite)propertyPageSite;
}
更改文本字段时通过事件处理程序调用的脏度检查
void OnDirty(bool isDirty)
{
_Dirty = isDirty;
// When this Method is called, the PageSite checks for Dirty Flag of all Optionspages.
if (_PropertyPageSite != null)
{
_PropertyPageSite.OnStatusChange();
}
}
我努力了
- 在干净的 Windows VM 的以下配置中发生崩溃
- Outlook 64 位,Outlook 插件 64 位
- Outlook 32 位,Outlook 插件 64 位
- Outlook 64 位,Outlook 插件 32 位
- Outlook 23 位,Outlook 插件 32 位
- 我将 Outlook 降级到 2021 的版本并且没有发生崩溃,这很可能意味着由于 Outlook 中的更新而出现问题
- 我尝试使用 WinDbg 进行检查,但我对此没有足够的了解。我确实从程序集和堆栈跟踪中添加了以下结果
- 我安装了可以运行的旧版本的应用程序,但它们有同样的问题
- 我试图查看是否有其他方法可以获取
PropertyPageSite对象,或者是否需要替换 dll 字符串,但我无法以其他任何方式使其工作
WinDbg 结果
堆栈跟踪
[0x0] outlook!SmoothScroll + 0x33fa4
[0x1] outlook!OlkGetResourceHandle + 0xd77d
[0x2] outlook!StdCoCreateInstance + 0x9e630
[0x3] outlook!SmoothScroll + 0x34f3a
[0x4] outlook!StdCoCreateInstance + 0x3c047
[0x5] outlook!StdCoCreateInstance + 0x8bf7
[0x6] outlook!RefreshOutlookETWLoggingState + 0x782b
[0x7] 0x7ffd28553c06
[0x8] MyOutlookAddin_28b66070000!MyOutlookAddin.OptionPage.OnDirty + 0x6d
[0x9] MyOutlookAddin_28b66070000!MyOutlookAddin.OptionPage.textBox_TextChanged + 0x55
[0xa] System_Windows_Forms_ni!System.Windows.Forms.Control.OnTextChanged + 0x96
....
拆卸。错误发生在最后一行
00007ff6`b3f47ba2 488b8f38020000 mov rcx, qword ptr [rdi+238h]
00007ff6`b3f47ba9 48894de7 mov qword ptr [rbp-19h], rcx
00007ff6`b3f47bad 4883c8ff or rax, 0FFFFFFFFFFFFFFFFh
00007ff6`b3f47bb1 48ffc0 inc rax
00007ff6`b3f47bb4 66393441 cmp word ptr [rcx+rax*2], si
版本
- Outlook:2206 build 16.0.15330.20260 64 位
- .net: 4.5.2
- Visual c++ 2010 可再发行版:10.0.40219
- 用于 Office 运行时的 Visual Studio 2010 工具:10.0.60724
是什么变化导致了这种行为?
编辑 2Requested TTD
-
您可以使用 ProcDump
procdump.exe -e -ma -o -w outlook.exe收集故障转储并使其可用吗? -
@DmitryStreblechenko 我将 procdump 放在描述中
-
收到感谢。您有机会创建时间旅行调试日志吗? (见blogs.windows.com/windowsdeveloper/2017/09/27/…)
-
@DmitryStreblechenko 已添加运行文件
-
然后我将热切地等待修复。感谢您迄今为止的帮助和研究。
标签: c# .net outlook outlook-addin office-addins