Нажатие диалогового окна AutomationElement - PullRequest
0 голосов
/ 26 октября 2018

Я автоматизирую установщик, так как он не имеет (функционального) / тихого переключателя. Это работает в основном хорошо, за исключением того, что я столкнулся с тем, что кажется дорожным блоком - страшным диалоговым окном. Похоже, это .

Что я пробовал:

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

Я в значительной степени растерялся, потому что мне бы очень хотелось, чтобы не нажимал эту кнопку вручную (что также портит остальную часть автоматической установки).

Я знаю, почему он не найден (или я так думаю); потому что это новый диалог, я думаю, что ввод не работает, потому что его отправка в неправильный процесс (родительский процесс диалогового окна, установщик) и сенсорный ввод, о котором я не знаю.

В документации не говорится о том, как работать с диалоговым окном (это также все 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;
}

1 Ответ

0 голосов
/ 26 октября 2018

Я бы проверил, что там, прямо перед тем, как идти за элементом.Я использую метод, подобный этому, чтобы получить все.

  /// <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");.Подсказка, как правило, не отображается из-за того, как быстро приложение щелкает объекты, поэтому у него будет (-1, -1) для своей позиции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...