[英]Clicking AutomationElement Dialogue Box
我正在自动化安装程序,因为它没有(功能性)/静音开关。 除了我遇到了一个似乎是路障 - 一个可怕的对话框之外,它几乎可以正常工作。 看起来像这样。
我试过的:
SendKey.Send/Wait(Enter/Escape)
PostMessage(proc.MainWindowHandle, WM_KEYDOWN, VK__RETURN, 0);
密钥注入进程
injector.SimulateTap((int) centre.X + 150, (int) centre.Y + 75);
触摸注入,不会在此特定窗口上注册,但所有其他窗口都可以正常工作。
Walking over the element as if it were just a normal element
我几乎不知所措,因为我非常希望不必手动按下这个按钮(这也会弄乱自动安装的其余部分)。
我知道为什么没有找到(或者我认为是); 因为它是一个新的对话,我认为 enter 不起作用,因为它发送到错误的进程(对话框的父进程,安装程序)和触摸注入我一无所知。
文档没有讲如何处理对话框(也是全C++)。
通常,我会遍历元素以找到下一个控件以继续安装。 有几个控件:
string[] EGalaxTouchInstallSequence = {
@"Next >",
"I accept the terms of the license agreement",
@"Next >",
"None",
null, //this is supposed to represent a dialogue popup
"OK",
"Support Multi-Monitor System",
@"Next >",
@"Next >",
@"Next >",
@"Next >",
@"Next >"
};
最初,我从窗口中获取所有句柄,如下所示:
AutomationElement UIElement = AutomationElement.FromHandle(SetupWindow);
我遍历列表:
foreach (string button in EGalaxTouchInstallSequence)
{
if (!FindAndClickElement(UIElement, button))
goto error;
}
FindAndClickElement
:
private bool FindAndClickElement(AutomationElement UIElement, string ElementName)
{
AutomationElement element = null;
Condition ControlProperty = new PropertyCondition(AutomationElement.NameProperty, ElementName);
AutomationElementCollection elements = UIElement.FindAll(TreeScope.Descendants, ControlProperty);
foreach (AutomationElement e in elements)
{
if (e.Current.Name.Contains(ElementName))
{
Console.WriteLine("Match with: " + ElementName);
element = e;
}
}
//Click code is further down, irrelevant at this stage
}
Element Exists
:
private bool ElementExists(AutomationElement UIElement, string ElementName)
{
Condition ControlProperty = new PropertyCondition(AutomationElement.NameProperty, ElementName);
AutomationElementCollection elements = UIElement.FindAll(TreeScope.Descendants, ControlProperty);
foreach (AutomationElement e in elements)
{
Console.WriteLine($"element name: {e.Current.Name}");
if (e.Current.Name.Contains(ElementName))
{
return true;
}
}
return false;
}
在你去获取元素之前,我会检查一下那里有什么。 我使用这样的方法来获取所有内容。
/// <summary>
/// Returns all children elements of an automation element.
/// </summary>
/// <param name="automationElement"></param>
/// <returns></returns>
public static List<AutomationElement> AllChildren(AutomationElement automationElement)
{
if (automationElement == null) throw new ArgumentNullException(nameof(automationElement));
AutomationElement firstChild = TreeWalker.RawViewWalker.GetFirstChild(automationElement);
if (firstChild == null)
return new List<AutomationElement>();
List<AutomationElement> children = new List<AutomationElement> { firstChild };
AutomationElement sibling;
int childIndex = 0;
while ((sibling = TreeWalker.RawViewWalker.GetNextSibling(children[childIndex])) != null)
{
children.Add(sibling);
childIndex++;
}
return children;
}
同样,正如我在评论中所说的那样,请确保您不会通过使用类似FindAll("...").FirstOrDefault(a => a.FirstChild().ClassName != "ToolTip");
东西意外找到工具提示FindAll("...").FirstOrDefault(a => a.FirstChild().ClassName != "ToolTip");
. 工具提示通常不会显示,因为应用程序点击事物的速度有多快,因此它的位置会有一个 (-1, -1)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.