【发布时间】:2019-03-31 07:25:16
【问题描述】:
我正在自动化安装程序,因为它没有(功能性)/silent 开关。它工作得很好,除了我遇到了一个似乎是路障的东西——一个可怕的对话框。 看起来像this。
我尝试过的:
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
我几乎不知所措,因为我非常希望不手动按下此按钮(这也会打乱自动安装的其余部分)。 p>
我知道为什么找不到(或者我想是的);因为它是一个新的对话,我认为 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;
}
【问题讨论】:
-
对话框是桌面的子级还是桌面的子级?我发现当我按类名查找窗口时,有时我会找到工具提示,因为它们是窗口。
-
它似乎是 InstallShield 安装程序的子进程 - 我检查了安装进程的子进程,但它没有名称或任何内容,因此很难假设该子进程是否只是内部InstallShield 安装程序的窗口,或者如果它是对话框,但我不确定如何找到,因为它没有任何其他子项。
-
所以在我们的 WPF 应用程序中,我做了这样的事情来防止自己找到工具提示。
FindAll("...").FirstOrDefault(a => a.FirstChild().ClassName != "ToolTip");这很慢,但我找到了最好的解决方案。 -
我可以尝试,但无论我如何操作(输入、触摸、退出等),窗口都要求我通过对话。我会看看我是否可以尝试找到一个工具提示(我不认为它是一个工具提示,但没有其他关闭的控件)。
标签: c# .net windows ui-automation