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

2024-03-09

In this 相关问题 https://stackoverflow.com/q/14716871/386205,我注意到 Visual Studio 的调试器能够枚举System.__ComObject http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.getobjectforiunknown.aspx引用,这是“当包装类型不明确时使用的隐藏类型”——例如,当您从另一个 COM 对象获取它并且不自己实例化它时获得的对象类型:

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

请注意,这与 VS2010 的“动态视图 http://blogs.msdn.com/b/habibh/archive/2009/09/22/debugging-a-com-object-runtime-callable-wrapper-with-visual-studio-2010.aspx“,我相信使用IDispatch http://en.wikipedia.org/wiki/IDispatch和 COM 反射来枚举 COM 对象的属性,而无需使用 PIA 和 .NET 反射。我正在处理的对象not实施IDispatch(他们也不实施IProvideClassInfo http://msdn.microsoft.com/en-us/library/windows/desktop/ms687303%28v=vs.85%29.aspx就此而言),因此,“动态视图”无法获取有关它们的任何信息:

有趣的是,夏普开发 http://www.icsharpcode.net/opensource/sd/的调试器无法列出以下成员System.__Comobjects (e.g. point.Envelope),仅强类型 RCW(例如point).

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

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

首先,它如何访问 PIA?它只查看当前加载的 PIA 还是动态加载它们(如果是,如何加载)?它如何确定要枚举哪个接口(可以有多个接口)的属性?它似乎只使用了一个,而不一定是第一个。来自文档 http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#//000100000195000000我正在使用的 API (ArcObjects) 中,这些对象的默认接口是IUnknown http://en.wikipedia.org/wiki/IUnknown,所以它也不只是使用默认接口。

在屏幕截图的示例中,它枚举成员的接口是IEnvelope http://help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/index.html#//002m00000169000000接口,它继承自IGeometry http://help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/index.html#/IGeometry_Interface/002m000001rm000000/界面。 VS2010怎么知道不枚举成员IGeometry相反,在我的测试中,如果您只是枚举 PIA 中的所有接口类型,哪个会首先出现?发生了一些非常聪明的事情,或者也许我错过了一些明显的事情?

我问的原因是开发者LINQPad http://www.linqpad.net/ 看起来愿意 https://stackoverflow.com/q/14716871/386205如果他知道 VS 是如何实现的,他就能实现相同的功能。因此,这里的一个好的答案可能会对改进这个非常流行的工具大有帮助。


操作方法如下:

  • 获取COM对象的IDispatch(替代可能的路径是IDispatchEx)
  • 获取对类型库的引用——IDispatch::GetTypeInfo http://msdn.microsoft.com/en-us/library/windows/desktop/ms221571%28v=vs.85%29.aspx
  • 加载类型库并枚举属性
  • 查询真实对象以获取已发现属性的值

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐