我有一个故障转储,我们正在讨论最终用户是否可以看到控件。使用 !do 看,我看不到任何包含与 Visible 属性匹配的真/假值的显式字段,这并不令人惊讶,因为我们可能处于 win32 领域。有谁知道如何推断 Visible 从转储文件返回的内容?
谢谢奥斯卡
我最初的想法是,这只是一个寻找正确领域的问题,但实际上它需要更多的挖掘。如果您查看 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,则需要查找父级并重复该技巧。对于我使用不必要的表单的简单示例。