我们正在开发一个供内部使用的WPF 4.0应用程序.
在某些客户端,由于UI自动化,我们遇到了巨大的性能问题(这些客户端安装了平板电脑服务笔,触摸等软件).
这是WPF 4.0的已知问题,例如:
我们已经能够在规格非常有限的机器上重现这个问题.在此机器上打开WPF窗口需要:
正如您所看到的,安装修补程序KB2484841是一项巨大的改进,但仍然没有安装ui Automation触发软件时运行速度快.
此外,我们无法控制在客户端安装哪些软件,因此很难为所有客户端推出此修复程序.
因此,是否可以为整个WPF应用程序"关闭"UI自动化?我知道它可以在每个UserControl的基础上完成,但它是否可以作为一个整体的应用程序?
我已经尝试过这篇文章中提供的代码,但没有成功.
谢谢你的时间,
科恩
我在测试或测试自动化方面非常陌生.现在我最近被分配到一个自动化UIF测试WPF应用程序的项目.在对MSDN和其他人进行一些搜索之后,我对是否应该使用Microsoft UI自动化库或VS 2010的新编码UI测试功能感到有点困惑.我没有清楚地了解这些适用于哪一个在哪些情况下,一个人有什么优势,另一个适合我(再一次,我有一个像WPF应用程序的CAD,错过了很多AutomationIds,我必须自动化其ui测试).请帮忙 !!!
我们正在使用Microsoft的UIAutomation框架来开发一个监视特定应用程序事件的客户端,并以不同的方式响应它们.我们已经开始使用该框架的托管版本,但由于延迟问题,转移到UIACOMWrapper中包含的本机版本.在我们(大规模)WPF应用程序中出现更多性能问题后,我们决定将其移至单独的终端应用程序(通过UDP将事件传输到我们的WPF应用程序),这似乎解决了所有性能问题.唯一的问题是,似乎每隔几分钟,TabSelection,StructureChanged,WindowOpened和WindowClosed的事件就会被捕获几分钟.令人惊讶的是,当发生这种情况时,仍会接收和处理PropertyChanged事件.我将发布我们的事件监视器的相关代码,但这可能无关紧要,因为我们在使用Microsoft自己的AccEvent实用程序时已经看到类似的行为.我不能发布受监控应用程序的代码,因为它是专有的和保密的,我可以说它是一个承载WPF窗口的WinForms应用程序,也非常庞大.有没有人在使用UI自动化框架时看到过这种行为?感谢您的时间.
这是监视器代码(我知道事件处理在这里的UI自动化线程上,但是将它移动到专用线程并没有改变任何东西):
public void registerHandlers()
{
//Register on structure changed and window opened events
System.Windows.Automation.Automation.AddStructureChangedEventHandler(
this.getMsAutomationElement(), System.Windows.Automation.TreeScope.Subtree, this.handleStructureChanged);
System.Windows.Automation.Automation.AddAutomationEventHandler(
System.Windows.Automation.WindowPattern.WindowOpenedEvent,
this.getMsAutomationElement(),
System.Windows.Automation.TreeScope.Subtree,
this.handleWindowOpened);
System.Windows.Automation.Automation.AddAutomationEventHandler(
System.Windows.Automation.WindowPattern.WindowClosedEvent,
System.Windows.Automation.AutomationElement.RootElement,
System.Windows.Automation.TreeScope.Subtree,
this.handleWindowClosed);
this.registerValueChanged();
this.registerTextNameChange();
this.registerTabSelected();
this.registerRangeValueChanged();
}
private void registerRangeValueChanged()
{
if (this.getMsAutomationElement() != null)
{
System.Windows.Automation.Automation.AddAutomationPropertyChangedEventHandler(
this.getMsAutomationElement(),
System.Windows.Automation.TreeScope.Subtree, this.handlePropertyChange,
System.Windows.Automation.RangeValuePattern.ValueProperty);
}
}
private void unregisterRangeValueChanged()
{
System.Windows.Automation.Automation.RemoveAutomationPropertyChangedEventHandler(
this.getMsAutomationElement(),
this.handlePropertyChange);
}
private void registerValueChanged()
{
if (this.getMsAutomationElement() != null)
{
System.Windows.Automation.Automation.AddAutomationPropertyChangedEventHandler(
this.getMsAutomationElement(),
System.Windows.Automation.TreeScope.Subtree, this.handlePropertyChange,
System.Windows.Automation.ValuePattern.ValueProperty);
}
}
private void …Run Code Online (Sandbox Code Playgroud) 我真的想知道,Inspect.exe如何获取它的UI元素,因为它获得的元素比UISpy多得多(两者都在Microsoft Windows SDK 7中可用)
1)我认为UISpy通过UIAutomation库获取它的元素,对吗?(尝试使用UIAutomation并获得完全相同的元素,显示UISpy)
2)Inspect.exe使用哪个库?因为它显示了一些带有MacromediaFlashPlayerActiveX的应用程序的UI元素,我需要在自己的UI-Automation-Application中获取,希望有人知道它.
编辑:Inspect也有一个"UI自动化"模式,它是否也使用UIAutomation库?关于它的奇怪之处在于,在Inspect中它还显示了比UISpy更多的元素.
先感谢您
.net ui-automation ui-spy microsoft-ui-automation inspect.exe
我正在开发一个C++应用程序,它使用UIAutomation接收与用户交互相关的重要事件的通知.我通过调用AddAutomationEventHandler来侦听窗口打开的事件,尝试了通过处理程序,但是我在退出之前停止通知和清理时遇到了问题.如果用户已启动某些应用程序(如Firefox),则调用RemoveAutomationEventHandlerhangs.(在这种情况下,调用RemoveAllEventHandlers也会挂起.)请注意,添加或删除事件处理程序的所有调用都在同一个非UI线程的上下文中完成.
注意:我在Windows 7和Windows 8上看到此行为.
关于为什么会发生这种情况或如何解决问题的任何想法?是什么让结构改变事件与其他事件不同?
我试图使用.NET UIAutomation OR White框架找到所有桌面窗口.我试过了 :
1.)
AutomationElement rootElement = AutomationElement.RootElement;
var winCollection = rootElement.FindAll(TreeScope.Subtree, Condition.TrueCondition);
Run Code Online (Sandbox Code Playgroud)
2.)
Desktop.Instance.Windows();
Run Code Online (Sandbox Code Playgroud)
两者都抛出ArgumentException.如果还有其他方法可以让我知道......
更新/答案:Desktop.Instance.Windows(); 工作正常,但它在使用VS2010调试代码时抛出异常.
我可以看到具有特定自动化ID的元素在Inspect工具中有子项:

但是当我尝试像这样检索它们时:
AutomationElement aPane = mainWindow.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.AutomationIdProperty, "8264"));
AutomationElementCollection theChildren = aPane.FindAll(TreeScope.Subtree, Condition.TrueCondition);
Run Code Online (Sandbox Code Playgroud)
该aPane元件被正确地恢复,但theChildren元件是空的.出了什么问题?
我目前正在使用库UIAutomation PS Extensions(https://uiautomation.codeplex.com/)自动安装GUI应用程序.当我针对现有的Windows用户会话运行它时,它的效果非常好.我运行我的PS脚本,它打开一个窗口,我可以点击按钮等等..
但是,从远程计算机调用此库时会出现问题.我通过PsExec从远程机器调用我的脚本(应该打开一个GUI窗口并开始控制它).这导致脚本无法在远程计算机上打开GUI窗口并开始产生各种异常.
作为解决方法,我可以使PsExec连接到远程主机上的特定现有会话,但不幸的是这不稳定,因为我无法保证会话的存在.
enyone是否知道是否可以强制PowerShell打开新的会话(交互式GUI),通过它我可以调用UIAutomation命令?
提前谢谢马修
powershell automation psexec ui-automation microsoft-ui-automation
我无法从流程内部收听自动化事件.我在下面写了一个示例,其中有一个带有单个按钮的简单WPF应用程序.使用TreeScope:Descendants在窗口上为Invoke事件添加自动化处理程序.
public MainWindow()
{
InitializeComponent();
Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
{
IntPtr windowHandle = new WindowInteropHelper(this).Handle;
Task.Run(() =>
{
var element = AutomationElement.FromHandle(windowHandle);
Automation.AddAutomationEventHandler(InvokePattern.InvokedEvent, element, TreeScope.Descendants,
(s, a) =>
{
Debug.WriteLine($"Invoked:{a.EventId.Id}");
});
});
}
private void button_Click(object sender, RoutedEventArgs e)
{
Debug.WriteLine("Clicked!");
}
Run Code Online (Sandbox Code Playgroud)
当我点击按钮时,这就是我得到的:
Invoked:20009
Clicked!
Invoked:20009
Run Code Online (Sandbox Code Playgroud)
为什么Invoked事件被处理两次?
如果我删除Task.Run我只能得到它一次,但我已经阅读了几个你不应该从UI线程调用自动化代码的地方(例如https://msdn.microsoft.com/en-us/ library/ms788709(v = vs.110).aspx).在真实代码中这样做也是不切实际的.
我在此示例中使用了UIAComWrapper库,但是我对UIAutomationClient库的托管版和COM版都有相同的行为.
在Windows窗体中,我们使用Infragistics UltraWinTree控件.
目标:使用UI Automation(UIAutomationClient.dll)折叠所有树项.
有关UI自动化的更多详细信息,请参阅:https://msdn.microsoft.com/en-us/library/ms747327(v = vs.110).aspx
下面是代码.
if (true == elementNode.TryGetCurrentPattern(InvokePattern.Pattern, out object patt))
{
invokePattern = patt as InvokePattern;
invokePattern.Invoke()
}
Run Code Online (Sandbox Code Playgroud)
问题:上一个treeitem没有崩溃.当我在UI Spy中看到元素时,对于最后一个treeitem"InvokePatternAvailable"属性显示为false.对于最后一个treeitem,只有Invoke Pattern不可用,因为如果条件不满足,则上面有这个原因.
我的问题是:这是折叠Infragistics treeitem的正确方法吗?或者Infragistics控件中是否有任何错误?
c# ×4
.net ×2
wpf ×2
automation ×1
infragistics ×1
inspect.exe ×1
powershell ×1
psexec ×1
ui-spy ×1
ui-testing ×1
ultratree ×1
windows ×1
winforms ×1
wpf-4.0 ×1