Comments (9)
Can you please measure each call individually (app.GetAllTopLevelWindows
, window.FindFirstDescendant
) to see which of those 2 is the slower one?
If it indeed is the first one, you can always directly search the window directly:
var window = automation.GetDesktop().FindFirstChild(cf =>
cf.ByControlType(ControlType.Window)
.And(cf.ByProcessId(app.ProcessId))
.And(cf.ByName("Client.Main.Views.AppendViewModel"))
);
from flaui.
When it gets all windows from the top level (desktop), UIA queries the Windows-Objects underneath and it might encounter a window (application) that is hanging for some time until it responds, making the whole request slow. If you want, you could try to get each window from the GetDesktop
individually and see, if there is one or a few that takes longer to get a response.
from flaui.
Could you provide some code with what you've done? Would be easier to get a better idea about what you're trying to do
from flaui.
var app = FlaUI.Core.Application.Attach("xxx.exe");
using (var automation = new UIA3Automation())
{
var window = app.GetAllTopLevelWindows(automation).FirstOrDefault(t => t.Name == "Client.Main.Views.AppendViewModel");
window.FindFirstDescendant(t => t.ByName("Accept")).AsButton()?.Invoke();
}
from flaui.
GetAllTopLevelWindows is slower, taking 3 seconds, but the new method you provided is effective, reducing the time to 0.2 seconds. Additionally, GetAllTopLevelWindows is not as slow as before, perhaps because my system has been restarted.
from flaui.
How do I enumerate it? The code in the loop passes quickly, and the time is concentrated on FindAllChildren.
foreach (var element in automation.GetDesktop().FindAllChildren(a => a.ByControlType(FlaUI.Core.Definitions.ControlType.Window)))
{
element.Name.Dump();
element.FindAllChildren();
}
from flaui.
How do I enumerate it? The code in the loop passes quickly, and the time is concentrated on FindAllChildren. foreach (var element in automation.GetDesktop().FindAllChildren(a => a.ByControlType(FlaUI.Core.Definitions.ControlType.Window))) { element.Name.Dump(); element.FindAllChildren(); }
In raw UIA you would var firstWindow = AutomationElement.RootElement.GetFirstChild(...);
with the condition that its control type is a window. Then you would get the next sibling of the first window by using the treewalker like we do here for getting the parent var nextSibling = Automation.TreeWalkerFactory.GetRawViewWalker().GetNextSibling(firstWindow);
. Eventually, this will return null when there are no more siblings. I believe the example in FlaUI would look something like this.
var element = automation.GetDesktop().FindFirstChild(a => a.ByControlType(FlaUI.Core.Definitions.ControlType.Window);
while (element != null)
{
//element.FrameworkAutomationElement gives access to the automation element that FlaUI wraps so that methods that are not implemented can be used
//once there are no more siblings this will be set to null and we will exit the loop
element = Automation.TreeWalkerFactory.GetRawViewWalker().GetNextSibling(element.FrameworkAutomationElement);
//dump information about the elements
}
You can find more examples of usage of the TreeWalker here. This unfortunately will be slower than just asking for FindAll
since this will result in multiple cross-process calls as opposed to a single batched call but if there is one window slowing things down it should still be proportionally slow compared to the other windows just with the added delay of making a call per window.
from flaui.
How do I enumerate it? The code in the loop passes quickly, and the time is concentrated on FindAllChildren. foreach (var element in automation.GetDesktop().FindAllChildren(a => a.ByControlType(FlaUI.Core.Definitions.ControlType.Window))) { element.Name.Dump(); element.FindAllChildren(); }
In raw UIA you would
var firstWindow = AutomationElement.RootElement.GetFirstChild(...);
with the condition that its control type is a window. Then you would get the next sibling of the first window by using the treewalker like we do here for getting the parentvar nextSibling = Automation.TreeWalkerFactory.GetRawViewWalker().GetNextSibling(firstWindow);
. Eventually, this will return null when there are no more siblings. I believe the example in FlaUI would look something like this.在原始的UIA中,你需要满足它的控件类型是一个窗口的条件.然后,你可以像我们在这里获取父窗口一样,使用树遍历器来获取第一个窗口的下一个兄弟窗口。最终,当没有兄弟节点时,这将返回null。我相信FlaUI中的例子看起来应该是这样的。var element = automation.GetDesktop().FindFirstChild(a => a.ByControlType(FlaUI.Core.Definitions.ControlType.Window); while (element != null) { //element.FrameworkAutomationElement gives access to the automation element that FlaUI wraps so that methods that are not implemented can be used //once there are no more siblings this will be set to null and we will exit the loop element = Automation.TreeWalkerFactory.GetRawViewWalker().GetNextSibling(element.FrameworkAutomationElement); //dump information about the elements }
You can find more examples of usage of the TreeWalker here. This unfortunately will be slower than just asking for
FindAll
since this will result in multiple cross-process calls as opposed to a single batched call but if there is one window slowing things down it should still be proportionally slow compared to the other windows just with the added delay of making a call per window.
I tested the following code based on your suggestion, and it speed is basically the same as FindAllChildren().
FlaUI.UIA3.UIA3Automation automation = new FlaUI.UIA3.UIA3Automation();
var element = automation.GetDesktop().FindFirstChild(a => a.ByControlType(FlaUI.Core.Definitions.ControlType.Window));
while (element != null)
{
var start = DateTime.Now;
element = automation.TreeWalkerFactory.GetRawViewWalker().GetNextSibling(element);
var end = DateTime.Now;
(end - start).Dump();
if (element == null) break;
element.ToString().Dump();
}
According to the test, I found that the time is concentrated in
"AutomationId:, Name:Program Manager, ControlType:窗格, FrameworkId:Win32",
which consumes more than 2500ms, while other windows usually only take a few tens of milliseconds.
from flaui.
@SunnyDesignor I have only ever experienced a slow down in getting a window when that window is not responding or the OnCreateAutomationPeer method is taking a long time to finish producing the automation peers for the controls. If it's not a .NET application it could be taking a longer time to respond to the WM_GETOBJECT message but I am not very familiar with how to dig into that.
from flaui.
Related Issues (20)
- Cannot find some existing elements by FindAllDescendants() HOT 3
- Create a new AutomationElement based on UserControl HOT 1
- Unable to get the text for ComboBoxItem HOT 2
- Could not find process with id HOT 4
- I cannot get the combo box list. HOT 2
- Process ID returned by FlaUI.Core.Application is different from windows process ID HOT 2
- When Flaui will support .net core 8.0 HOT 2
- Instance of an object from System.Windows.Input halves the point passed to Mouse.Click HOT 1
- How to find and write this textbox
- FindAllDescendants does not return all descendants HOT 8
- how to load a windows store app photo app
- Jenkins machines cannot capture elements with ControlType: UIA_WindowControlTypeId (0xC370) and LocalizedControlType: "dialog" HOT 1
- Taking text pattern information from grid header and cells
- The latest release (4.0.0) depends on deprecated (and vulnerable) libraries
- Enhance GetRowsByValue Method to Support Partial Matching and Case Sensitivity
- FindFirstDescendant error HOT 1
- who can help me? HOT 1
- XPath query does not return root.
- Facing issue for Java Application automation, Inspect doesn't showing elements in inspect list, and if i tried to use xpath for controls, it is also not working,
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from flaui.