Visual Studio的调试器/交互式窗口如何在.NET中转储COM对象的属性?

时间:2013-02-10 13:20:06

标签: visual-studio-2010 com com-interop linqpad arcobjects

在这个related question中,我注意到Visual Studio的调试器能够枚举System.__ComObject引用的属性,这是“当包装类型不明确时使用的隐藏类型” - 例如,从另一个COM对象获取对象时获得的对象类型,并且不自行实例化它:

COM Object Debug View

此外,如果您只是将一个COM对象的标识符写入立即窗口,其属性和值将被类似地转储:

COM Object Immediate Window

请注意,这与VS2010的“Dynamic View”是分开的,我相信使用IDispatch和COM反射来枚举COM对象的属性,而不使用PIA和.NET反射。我正在使用的对象实现IDispatch(他们也没有实现IProvideClassInfo),因此,“动态视图”无法获取任何内容有关他们的信息:

Dynamic View

有趣的是,SharpDevelop的调试器无法列出System.__Comobject的成员(例如point.Envelope),只能列出强类型的RCW(例如point)。

SharpDevelop debugger

那么Visual Studio如何才能做到呢?

我相信在这种情况下,这是因为主互操作程序集存在这些对象支持的接口的定义,并且Visual Studio可能使用反射来枚举支持的接口和属性。那是准确的吗?如果是这样,它是如何工作的?

对于初学者来说,它如何访问PIA?它只查看当前加载的PIA还是动态加载它们(如果是,如何)?它如何确定哪个界面可以有多个枚举属性?它似乎只使用一个,而不一定是第一个。从我正在使用的API的documentation(ArcObjects)中,这些对象的默认界面是IUnknown,因此它不仅仅使用默认界面。

在屏幕截图的示例中,它枚举成员的接口是IEnvelope接口,它继承自IGeometry接口。 VS2010如何知道不要枚举IGeometry的成员,在我的测试中,如果您只是枚举PIA中的所有接口类型,它会首先出现?一些非常聪明的事情,或者我错过了一些明显的东西?

我问的原因是LINQPad appears willing的开发人员如果知道VS是如何实现相同的功能的话。所以这里一个好的答案可以帮助改进这个非常受欢迎的工具。

1 个答案:

答案 0 :(得分:2)

这是怎么做的:

  • 获取COM对象的IDispatch(备选可能路径为IDispatchEx
  • 获取对类型库的引用 - IDispatch::GetTypeInfo
  • 加载类型库和枚举属性
  • 查询实际对象以查找已发现属性的值

其他增强功能适用:查询IPersist*系列接口或IProvideClassInfo,或者获取对象的类型库的引用并发现属性。