使用GetRefTypeInfo进行无法捕获的COMException

时间:2016-05-26 14:26:27

标签: c# interface com com-interop

我有一个函数,其作用是返回COM类型的名称;它在x64上运行正常,但在迭代Excel类型库中的COM类型(以及MS-Project,也可能是其他我不知道的)中间崩溃,我似乎无法能够对catch抛出的异常做任何事情。

  

System.Reflection.TargetInvocationException未处理   消息:mscorlib.dll中发生未处理的“System.Reflection.TargetInvocationException”类型异常   附加信息:调用目标抛出了异常。

这导致AccessViolationException,导致EXCEL.EXE主机进程突然死亡

我能够添加一些调试输出,并确切地确定哪个成员正在爆炸:

  
      
  • 查询成员SheetPivotTableBeforeDiscardChanges的AsTypeName
  •   
  • 会员EXCEL.EXE; Excel.IAppEvents.SheetPivotTableBeforeDiscardChanges   (对象)成功添加
  •   
  • 查询参数Sh
  • 的AsTypeName   
  • 参数EXCEL.EXE; Excel.IAppEvents.Sh(Object)已成功添加
  •   
  • 查询参数TargetPivotTable
  • 的AsTypeName   

当Excel类型库开始加载时,整个VBA类型库已成功加载。如果我在MS-Word主机中运行我的进程,一切运行正常,所以看起来某些关于TargetPivotTable的{​​{1}}参数的类型没有就像我写的那样来查询它。

IAppEvents.SheetPivotTableBeforeDiscardChanges

以下是贡献者能够从MS-Project主机获取的堆栈跟踪的相关部分:

case VarEnum.VT_USERDEFINED:
    int href;
    unchecked
    {
        if (Marshal.SizeOf(typeof (IntPtr)) == sizeof (long))
        {
            href = (int) desc.lpValue.ToInt64();
        }
        else
        {
            href = desc.lpValue.ToInt32();
        }
    }
    ITypeInfo refTypeInfo;
    info.GetRefTypeInfo(href, out refTypeInfo); // <~ boom
    return GetTypeName(refTypeInfo);

代码获得System.Runtime.InteropServices.COMException (0x80004005): Error HRESULT E_FAIL has been returned from a call to a COM component. at System.Runtime.InteropServices.ComTypes.ITypeInfo.GetRefTypeInfo(Int32 hRef, ITypeInfo& ppTI) at Rubberduck.Parsing.Symbols.ReferencedDeclarationsCollector.GetTypeName(TYPEDESC desc, ITypeInfo info) in c:\Users\Andrew\Documents\GitHub\Rubberduck\Rubberduck.Parsing\Symbols\ReferencedDeclarationsCollector.cs:line 95 at Rubberduck.Parsing.Symbols.ReferencedDeclarationsCollector.GetTypeName(TYPEDESC desc, ITypeInfo info) in c:\Users\Andrew\Documents\GitHub\Rubberduck\Rubberduck.Parsing\Symbols\ReferencedDeclarationsCollector.cs:line 89 at Rubberduck.Parsing.Symbols.ReferencedDeclarationsCollector.CreateFieldDeclaration(ITypeInfo info, Int32 fieldIndex, DeclarationType typeDeclarationType, QualifiedModuleName typeQualifiedModuleName, Declaration moduleDeclaration) ,因此它从该指针获取VT_PTR(第89行),然后递归;然后,相同的代码会获得TYPEDESC,因此它会从VT_USERDEFINED的{​​{1}}(第95行)获得ITypeInfo,而通常我得到lpValue并获取类型的名称。出于某种原因,在32位上下文TYPEDESC拒绝合作并将所有内容都发送到火焰中。

完整上下文,这是完整的相关代码:

ITypeInfo

那个GetRefTypeInfo块中有什么东西看起来好像在等待在32位上下文中爆炸吗?

0 个答案:

没有答案