自定义内存窗口的Visual Studio扩展

时间:2014-04-09 10:08:12

标签: visual-studio debugging com visual-studio-extensions visual-studio-package

我在Visual Studio Extension包中的自定义工具窗口应该在VS2012和VS2013的调试会话期间评估自定义表达式。最终目标是构建图形监视窗口。因此,我必须从调试引擎中获取表达式结果的值。

评估通过

正常运行
IDebugStackFrame2 -> IDebugExpressionContext2 -> ParseText 
IDebugExpression2 -> EvaluateSync -> IDebugProperty2

此处的第一个问题:在Visual Studio 2013上ParseText()无法正确报告错误。但是检索到的IDebugProperty2是有效的(对于有效的表达式)。在VS2012上,我得到了无效表达式的正确错误。

这是真正的问题开始的地方。结果Property2表示复杂的自定义对象。为了使其可视化,需要检索来自其中一个 base 类的特定属性。在我目前的尝试中,我使用IDebugProperty2.EnumChildren()将其成员移动到类层次结构中的正确位置,类似于在Visual Studio中的Locals窗口中执行的操作:

[result] -> base -> Raw -> base -> Non-public Members -> [private field] ... a.s.o.

这在某种程度上有效但引入了以下问题:

问题1:获取某个复杂对象的内部成员

从EnumChildren()收到的成员及其订单似乎取决于一些对我来说不明显的因素: *对象是否附加了Debug Visualizer? (VS2013忽略EnumChildren中的enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_VALUE_RAW并返回美化版本+“Raw View”节点,VS2012按预期工作) *是否显示“非公开会员”节点?有时候,它有时并不是 - 它不依赖于它所依赖的东西 *设置'只是我的代码'(?我在几个帖子中读到它但无法确定可靠的规则) * ...必须有其他依赖项?

这被证明是一种真正 hacky方式来获取某个复杂表达式结果对象的内部成员。什么是更好的方法?使用IDebugProperty3和一些Debugger Visualizer技巧?任何指针都会很棒。

问题2:VS2012无法提供内存字节

一旦我拥有结果对象的私有成员,我使用IDebugProperty2.GetMemoryBytes()来“序列化”其值(一个普通的System.Array)并将其传输到我的自定义工具窗口。虽然这在VS2013中有效,但在VS2012中IDebugProperty2.GetMemoryBytes()始终返回VS_Constants.S_FALSE。我真的没有想法。由于VS2012中有一个内存窗口,所以应该有一些方法可以让它在这里工作吗?我错过了什么?

用于查询内存API的代码:

IDebugMemoryContext2 memCtx = null;
IDebugMemoryBytes2 memBytes = null;

// getting the memory context is working ok
if (tmpProperty2.GetMemoryContext(out memCtx) == VSConstants.S_OK

  // VS2012 fails here, always returns S_FALSE, memBytes remains null:
  && (tmpProperty2.GetMemoryBytes(out memBytes) == VSConstants.S_OK)) { 
  ...

更多背景信息:

OS: Windows 8 and 8.1 
Visual Studio: 2012 / 2013
Tool Window built with MPF (C#) in VS2013, (removed all vers. 12 references from the package before deploying to VS2012)
Debug engines: C# and Visual Basic

0 个答案:

没有答案