【问题标题】:How does Visual Studio's debugger/interactive window dump the properties of COM Objects in .NET?Visual Studio 的调试器/交互式窗口如何在 .NET 中转储 COM 对象的属性?
【发布时间】:2013-01-25 17:30:19
【问题描述】:

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

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

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

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

那么 Visual Studio 是如何做到的呢?

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

首先,它如何访问 PIA?它只查看当前加载的 PIA 还是动态加载它们(如果是,如何加载)?它如何确定枚举属性的接口,其中可以有很多?它似乎只使用一个,不一定是第一个。从我正在使用的 API (ArcObjects) 的documentation 来看,这些对象的默认接口是IUnknown,因此它也不仅仅是使用默认接口。

在截图的例子中,它枚举成员的接口是IEnvelope接口,它继承自IGeometry接口。 VS2010怎么知道不枚举IGeometry的成员,在我的测试中,如果你只枚举PIA中的所有接口类型,它首先出现?发生了一些非常聪明的事情,或者我可能遗漏了一些明显的事情?

我问的原因是LINQPadappears willing 的开发人员如果知道 VS 是如何做到的,就可以实现相同的功能。因此,这里的一个好的答案可以大大有助于改进这个非常流行的工具。

【问题讨论】:

  • 由于Point类的Envelope属性的类型在PIA中定义为IEnvelope,VS可以dump,不需要特殊机制。
  • 嗯,真的那么简单吗?此信息是否仅在调试时可用? (如何)在运行时可以获得相同的信息?以及为什么 SharpDevelop 的调试器不做同样的事情(也许他们只是不关心)。
  • 是的,非常简单。当您只有 System._ComObject 时会更复杂,但是当您可以将它们转换为 ComImport .NET 接口时,您就可以访问这些接口布局。它随时可用,包括智能感知。我不了解 SharpDevelop。

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


【解决方案1】:

这是怎么做的:

  • 获取 COM 对象的IDispatch(可选路径为IDispatchEx
  • 获得对类型库的引用——IDispatch::GetTypeInfo
  • 加载类型库并枚举属性
  • 查询真实对象以获取已发现属性的值

附加增强选项适用:查询IPersist* 系列接口或IProvideClassInfo 以获取对象类型库的引用并发现属性。

【讨论】:

  • 正如我所写,这些对象都没有实现这些接口。实际上其中一些实现了IPersist,但不是全部。我必须检查一下哪些可以,哪些不可以,并将其与 VS2010 能够找到的有关它们的内容进行比较。
  • IDispatchEx, IProvideClassInfo2(嗯,这个是典型的,不是IProvideClassInfo)——应该有什么
  • 不,这两个都不是。
  • 啊,一定是IPersist。我尝试了一个没有实现IPersist 的不同对象,VS 在调试视图中没有显示任何内容。
  • 我会说你在这里遗漏了一些东西,并且获取类型库引用的魔力要少得多。 point.Envelope 单独看起来像是启用了类型库的调用,因此它的结果应该已经将类型信息引用嵌入到 __ComObject 中。
猜你喜欢
  • 1970-01-01
  • 2015-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多