我正在尝试开发允许使用Microsoft非托管UIAutomation API测试应用程序用户界面的库。我很难解决有关从另一个线程(例如事件处理程序)访问元素的实现问题。我正在使用interop dll访问UIAutomation,所以API初始化看起来像这样:static public IUIAutomation automation = new CUIAutomation();
。
例如:我正在订阅窗口打开事件:
automation.AddAutomationEventHandler(UIA_EventIds.UIA_Window_WindowOpenedEventId, automation.GetRootElement(), TreeScope.TreeScope_Subtree, null, this);
然后,当我在某个随机WinForms应用程序中调用按钮时,该应用程序打开对话框窗口,我进入HandleAutomationEvent(IUIAutomationElement sender, int eventId)
我想通过使用
访问对话框中的“是”按钮
sender.FindFirst(tree,MyClass.automation.CreatePropertyCondition(UIA_PropertyIds.UIA_NamePropertyId, "YES"));
由于无法从单线程单元访问COM对象,因此搜索需要很长时间。我无法从Microsoft文档中获得工作的方法:
https://docs.microsoft.com/en-us/windows/desktop/winauto/uiauto-threading
我尝试从另一个线程订阅事件,并尝试从另一个具有FindAll
属性的线程调用元素访问函数,例如FindFirst
或[MTAThread]
,但我无法获取任何有效的方法-效果仍然相同。我想知道是否有一个选项可以将元素包含在MTA中,即使不是线程安全的也是如此。对于C#,WinForms和COM Objects,我是一个总的入门者,因此,我希望能提供所有有用的信息。