我可以看到具有特定自动化ID的元素在Inspect工具中有子项:
但是当我尝试像这样检索它们时:
AutomationElement aPane = mainWindow.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.AutomationIdProperty, "8264"));
AutomationElementCollection theChildren = aPane.FindAll(TreeScope.Subtree, Condition.TrueCondition);
正确检索aPane
元素,但theChildren
元素为空。任何想法出了什么问题?
答案 0 :(得分:11)
在极少数情况下,我发现Find*
调用找不到所有自动化对象。我在其中看到的唯一一致的情况是WPF TextBlock
在数据模板中控制时,这些调用将无法找到它。在这些情况下,您可以尝试RawViewWalker
,它可能更接近Inspect在内部所做的事情。
public static IEnumerable<AutomationElement> FindInRawView(this AutomationElement root)
{
TreeWalker rawViewWalker = TreeWalker.RawViewWalker;
Queue<AutomationElement> queue = new Queue<AutomationElement>();
queue.Enqueue(root);
while (queue.Count > 0)
{
var element = queue.Dequeue();
yield return element;
var sibling = rawViewWalker.GetNextSibling(element);
if (sibling != null)
{
queue.Enqueue(sibling);
}
var child = rawViewWalker.GetFirstChild(element);
if (child != null)
{
queue.Enqueue(child);
}
}
}
答案 1 :(得分:2)
有点迟到的答案,但我想纠正这里选择的答案。是的,确实VS提供的COM包装器可能使用不同的UIAutomationClient.dll,并且在调用UIAutomation方法时使用本机代码与托管代码不同,但是这里提出的问题是另一个问题。 (顺便说一句,您可以使用托管代码中的COM包装器来调用UIAutomation dll的正确版本,这将解决像“inspect.exe找到它但我的托管代码不能”的问题。)
我也碰到了这里问的问题(我的是:FindAll(TreeScope.Children,TrueCondition)没有返回任何东西,尽管FindFirst()成功地在同一个控件上返回了孩子)。
我尝试了使用RawViewWalker查找孩子的mike-z方法,它适用于这种情况。我正在写这个单独的答案,说它不是Find *方法的问题,而是FindAll和amp;之间的区别。导致八月问题的FindFirst方法。
在MS工具方面,不一致的行为似乎是常态。这个更新的原因是,我使用C#对我的tlbimp.exe'd RCW遇到了类似的问题,这次我写了一个直接等效的C代码,令我惊讶的是它在C#代码下工作得很好在尝试查找简单的OpenFileDialog控件时,拒绝以任何方式工作,然后在主窗体上另一个控件。这两个世界的唯一区别是神秘的MS RCW魔法。我不确定是否使用自动创建的COM包装器(通过tlbimp)或其他方式处理编组。并且为创建的界面显示的[ComConversionLoss]属性听起来不对我。无论如何我现在正在考虑手动制作COM接口或将我的整个项目转换为原生环境。
答案 2 :(得分:1)
实际上问题是Inspect.exe是用 unmanaged 代码编写的,而我试图在 managed 代码中获得相同的结果。非托管代码返回的结果与托管版本略有不同(例如,管理代码将返回控件类型document,其中非托管代码将在我的应用程序中返回edit。
虽然花了一些时间来理解它,但非托管代码更快,更准确,因此更可靠。
可以在Microsoft Windows UI Automation博客中找到C#的非托管UI自动化代码的一些示例。 G。 here,
答案 3 :(得分:1)
托管和非托管UI自动化之间的区别是因为托管使用旧实现,但Inspect直接使用COM,这是更新版本3.0
答案 4 :(得分:0)
我原来的例子很简单。我尝试使用3种技术访问孩子:
只有VB6(非托管)代码提供与Microsoft的Inspect工具相同的结果。我相信这证实了其他人在上面所说的内容:微软在.Net中实现UI自动化存在严重问题。可能唯一的解决方案是在.Net中编写自定义UI自动化客户端,但这假设目标应用程序中的UI自动化服务器行为正常。这些是我无法控制的,因为目标应用程序是由其他公司编写的,而不是我的。