为什么UISpy可以看到的控件 FindFirst却找不到
来源:互联网 发布:软件推荐 编辑:程序博客网 时间:2024/04/29 21:53
如果你是通过Accessibility来做Windows下的界面自动化测试,即用UI Automation(UIA)这套框架来做的,那估计你应该用过UISpy这个程序(如果你还不知道UISpy这个程序可以点击此处了解http://technet.microsoft.com/zh-cn/library/ms727247)
如果你想在自己的程序中查找其它程序的界面上的按钮等控件,可以使用AutomationElement.FindFirst或TreeWalker类来实现,不知你是否遇到过在UISpy中可以看到某个控件但用AutomationElement.FindFirst或TreeWalker却怎么也无法找到的情况。以下是研究了很久才找到的解决方案:
需要用异步委托,来封装AutomationElement.FindFirst,否则直接调用此函数返回的结果会和UISpy看到的有差别,后来又试了一下,其实直接新建一个线程并启动,最后等线程结束后也可以看到期望的结果。异步委托应该也是通过多线程来实现的,看来问题关键是AutomationElement.FindFirst或TreeWalker等UIA的操作需要在单独的线程中来完成,注意以上使用UIA的程序和被测程序并不是同一个,所以为什么需要使用单独的线程我也不是很清楚。
PS:异步委托代码所在类的父类中不能含有ServicedComponent,否则结果也会和UISpy不同
另外还有两点需要注意:
1.发现部分机器上UISpy看到的结果和我的机器有差别(会有节点丢失的情况),这时直接调AutomationElement.FindFirst的结果反而可以找到“丢失的”节点。
2.如果只调用一次FindFirst在某些特殊情况下还是会出现找不到控件的情况,但调用第二次就可以找到了,。。。UIA的bug真多啊
以下附上可以解决上述几个问题的封装了AutomationElement的类
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace UITester{ using System.Windows.Automation; /// <summary> /// 扩展AutomationElement的功能 当前仅限于FindFirst /// </summary> public class myAutomationElementEx { private AutomationElement parent_element = null; private AutomationElement find_element = null; private TreeScope _findScope = TreeScope.Descendants; private Condition _find_condition = null; private delegate void FindElementDelegate(); private FindElementDelegate delegate2 = null; public myAutomationElementEx() { delegate2 = new FindElementDelegate(FindFirst); } /// <summary> /// 扩展AutomationElement的FindFirst /// </summary> /// <param name="start"></param> /// <param name="findScope"></param> /// <param name="find_condition"></param> /// <returns></returns> public AutomationElement FindFirst(AutomationElement start, TreeScope findScope, Condition find_condition) { parent_element = start; _findScope = findScope; find_element = null; _find_condition = find_condition; //必须先用普通方式查找 否则在部分机器上会有找不到控件的情况 在这类机器上UISpy确实看不到部分控件 但用普通方式却可以找到 find_element = parent_element.FindFirst(_findScope, _find_condition); if (null == find_element) { //部分控件找第二次才能找到 find_element = parent_element.FindFirst(_findScope, _find_condition); } if (null != find_element) { return find_element; } //不用这种方式的话 在第一次生成的窗体内(如对话框)搜到的控件会比实际的少 IAsyncResult asyncResult = delegate2.BeginInvoke(null, null); delegate2.EndInvoke(asyncResult); return find_element; } private void FindFirst() { find_element = parent_element.FindFirst(_findScope, _find_condition); } }}
- 为什么UISpy可以看到的控件 FindFirst却找不到
- 对话框中添加控件时,CMyDialog类中并没有CButton类的对象,却可以响应鼠标消息,为什么?
- 为什么普通用户可以看到其他用户创建dblink的密码?
- 为什么我的网页分享朋友圈仅仅自己可以看到
- 手机可以找到wifi,笔记本却找不到
- 为什么指定了坐标却找不到资源?
- 为什么指定了坐标却找不到资源?
- 为什么窗体中可以引用WCF服务,自定义控件中却不行?
- findfirst函数的用法
- 前两天看到微软提出的关于网络的“推”的理念,可是现在却找不到了,有谁知道?
- FindFirst
- Debug版本的Dll可以正常工作,Release版本却提示找不到dll
- Ubuntu可执行文件 ls 可以看到,执行却提示不存在
- Ubuntu可执行文件 ls 可以看到,执行却提示不存在
- 为什么我的findviewbyid 找不到布局中的控件
- 初学iOS,刚看到控件的strong&weak问题,如果答的不对还请指正。首先有一点,在OC中,如果对象没有强引用,就会被自动释放,那么为什么控件还可以设为weak?
- 初学iOS,刚看到控件的strong&weak问题,如果答的不对还请指正。首先有一点,在OC中,如果对象没有强引用,就会被自动释放,那么为什么控件还可以设为weak?
- 为什么有时候写的文章在外面可以看到连接,有时候完全看不到?
- extjs3.3.0图片放大缩小实现
- extjs3.3.0+struts2.1.8.1+spring3.0.4+hibernate3.5.4+oracle10g实现动态树
- VC6升级到VS2008(VC9.0)的变化
- Java对象的强、软、弱和虚引用
- 2011-9-3 敢问自己在做什么
- 为什么UISpy可以看到的控件 FindFirst却找不到
- Ubuntu10.04常用命令
- 关于代码复杂度的一点想法
- 投资大师罗杰斯给女儿的12 封信
- vb.net数据库异步操作(二)
- Reading Think in Java 【0】
- gcc make file demo
- HDU/HDOJ 4004 2011大连赛区网络赛 D题
- [Cocoa]深入浅出 Cocoa 之 Core Data(2)- 手动编写代码