繁体   English   中英

如何强制 UI 自动化树刷新

[英]How to force UI automation tree refresh

我目前正在尝试使用System.Windows.Automation来自动化 chrome 实例,但在某个时候AutomationElement.FindAll(TreeScope.Children, Condition.TrueCondition); 总是返回 0 个孩子,但我可以在 inspect.exe 中看到它们。 当我在 inspect.exe 中点击刷新时,元素也会显示在我的应用程序中。

在寻找解决方案时,我发现了这篇SO post,OP 或多或少有相同的问题。 建议使用的答案:

SystemParametersInfo( SPI_SETSCREENREADER, TRUE, NULL, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
PostMessage( HWND_BROADCAST, WM_WININICHANGE, SPI_SETSCREENREADER, 0);

我将其实现为:

[DllImport("user32.dll", SetLastError = true)]
static extern bool SystemParametersInfo(int uiAction, int uiParam, IntPtr pvParam, int fWinIni);

[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

....

const int SPI_SETSCREENREADER = 0x0047;

IntPtr inptrnull = IntPtr.Zero;
const int SPIF_UPDATEINIFILE = 0x01;
const int SPIF_SENDCHANGE = 0x02;


IntPtr HWND_BROADCAST = new IntPtr(0xffff);
const int WM_WININICHANGE = 0x001A;

SystemParametersInfo(SPI_SETSCREENREADER, 1, inptrnull, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
PostMessage(HWND_BROADCAST, WM_WININICHANGE, SPI_SETSCREENREADER, 0);

但它没有效果。

我错过了什么? 有其他/更好的方法吗?

看起来您正在使用过时的托管 UIA 实现 (System.Windows.Automation)。 这是一个已知的案例,它不能返回所有的孩子,这可能是原因。

根据文档

对于 Windows 7,已在组件对象模型 (COM) 中重写了 API。 尽管早期版本的 UI 自动化中引入的库函数仍被记录在案,但不应在新应用程序中使用它们。

您可以尝试改用UIA COM 接口(Inspect 使用相同的方法):

  1. 向您的项目添加对 COM -> UIAutomationClient 的引用。 这将为您生成一个包装器,因此可以在代码中以通常的 OO 样式访问 COM 接口。

  2. 创建一个 UI 自动化对象并使用 UIA 元素完成您的工作:

     IUIAutomation automation = new CUIAutomation(); // Start with the root element; you could also get an element from the point or current focus IUIAutomationElement element = automation.GetRootElement(); IUIAutomationElementArray foundElements = element.FindAll(TreeScope.TreeScope_Children, automation.CreateTrueCondition()); for (int i = 0; i < foundElements.Length; i++) { IUIAutomationElement currentElement = foundElements.GetElement(i); // do your stuff with the element: get its properties, etc }
  3. 如果以上没有帮助,您可以尝试使用 RawTreeWalker 而不是调用 FindAll() 来遍历 UI 树:

     IUIAutomationTreeWalker walker = automation.RawViewWalker; IUIAutomationElement child = walker.GetFirstChildElement(element); var sibling = walker.GetNextSiblingElement(child); while (sibling != null) { // do your stuff with sibling elements (get their child elements, etc) sibling = walker.GetNextSiblingElement(child); }
  4. 我之前使用 UIA 自动化了 Chrome,据我所知,它对 UIA 调用的响应可能有点奇怪:例如,有时它返回一个容器元素而不是实际的元素(按钮、编辑等)。 我通过多次尝试解决了这个案例,直到我最终检索到了预期的结果。 如果您也多次调用 FindAll() 会怎样?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM