如何使用windbg判断一个.Net控件是否可见

3

我得到了一个崩溃转储文件,我们在讨论一个控件是否对最终用户可见。通过使用 !do 命令,我无法看到任何显式字段来保存与 Visible 属性匹配的 true/false 值,这并不奇怪,因为我们可能进入了 win32 领域。有人知道如何从转储文件中推断出 Visible 属性应该返回什么值吗?

谢谢 Oskar

1个回答

4

我的初始想法是只需要查找正确的字段,但实际上需要更深入的挖掘。如果您在反编译工具Reflector中查看Control类,您会发现Visible属性调用了GetVisibleCore方法,该方法将内部状态字段与值2(这恰好是常量STATE_VISIBLE)进行比较。

因此,要确定控件是否可见,我们需要定位状态字段并进行一些位操作。

如果您有实例的地址,可以执行以下操作:

.shell -ci "!do <ADDRESS>" grep state   (use findstr, if you don't have grep)

输出结果类似于以下内容:
0:000> .shell -ci "!do 015892a4" grep state
03aeedcc  400112c       4c         System.Int32  1 instance 17432589 state  <=== HERE!
03aeedcc  400112d       50         System.Int32  1 instance     2060 state2
049ac32c  40011ef       d0 ...lized.BitVector32  1 instance 01589374 state
03aeedcc  40011f0      ad4         System.Int32  1   static        1 stateScalingNeededOnLayout
03aeedcc  40011f1      ad8         System.Int32  1   static        2 stateValidating
03aeedcc  40011f2      adc         System.Int32  1   static        4     stateProcessingMnemonic
03aeedcc  40011f3      ae0         System.Int32  1   static        8 stateScalingChild
03aeedcc  40011f4      ae4         System.Int32  1   static       16 stateParentChanged

请注意,这里有两个状态字段。我没有深入研究为什么会出现这种情况,但您需要的是System.Int32。在我的示例中,它的值为17432589。

GetState中的代码如下:

return ((this.state & flag) != 0);

现在只需要执行(17432589 & 2) != 0,您就可以获得特定实例的可见状态。

实际上,您可能需要更进一步。如果以上返回false,则需要查找父级并重复操作。对于我使用的简单示例(使用表单),这是不必要的。


非常好,现在我知道控件是可见的(以及我的用户权限...),并且已经在其他地方验证了我的进程中的服务器状态与控件所说的不一致,因此错误必须在两者之间的某个地方。 :) - Oskar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接