by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Vasily Ryabov
    @vasily-v-ryabov
    Notepad++ умеет конвертировать кодировки, например.
    Квасок
    @Kvacdopil_twitter
    Привет. Есть сценарий: нативное приложение win, которое редиректит в Chrome для авторизации.
    Проблема: скрипт не запустится, если Chrome пока не существует, ибо ему соединиться не с чем. Как заставить выполняться скрипт, даже если процесса Chrome с нужным окном еще нет?
    Oleg
    @eratheo
    Василий, добрый день. А была ли возможность посмотреть по моим вопросам? По combobox?
    Vasily Ryabov
    @vasily-v-ryabov
    @Kvacdopil_twitter Привет. У метода .connect(...) есть параметр timeout в секундах. По умолчанию он не ждёт, а с таймаутом ждёт. Возможно, в будущем сделаем как везде - по умолчанию 5 секунд. Но сейчас пока так.
    @eratheo Добрый день. Вообще не было времени. Чтобы точно не потерялось, лучше GitHub issue завести. Я его на milestone 0.7.0 повешу, чтобы сделать в этом году. :)
    Vasily Ryabov
    @vasily-v-ryabov
    @eratheo завел вот: pywinauto/pywinauto#916
    @eratheo быстро обещать не могу, на карантине времени только убавилось. Первый приоритет - поддержка Линукса и макоси + рефакторинг, всё вместе это будет мажорный релиз 0.7.0. Все даты условны и взяты из идеального мира.
    Oleg
    @eratheo
    @vasily-v-ryabov спасибо! Остался вопрос по выбору элемента в комбо боксе или другом элементе. Если при выборе нужно подтверждения выбора, то у меня timeout error. Проблема появляется на выборе элемента из комбобокса - т.е. этот код не завершается, потому что появляется окно. И от выбора в этом окне уже зависит будет ли выбран элемент или нет.
    Vasily Ryabov
    @vasily-v-ryabov
    @eratheo правильно я понимаю, что при вызове метода .select("string item") происходит зависание, которое снимается ручным нажатием на confirmation диалоге? Такое я видел иногда. Тут помогло бы использование Thread'ов. Поскольку далеко не все такие обработчики на стороне приложения зависают, то внутрь метода встраивать Thread - это гадать на кофейной гуще. Если только явный параметр .select("something", blocking=False) просунуть, например. Скажем, я такое видел только для .invoke() у некоторых менюшек, с комбо боксами вроде не встречал.
    Oleg
    @eratheo
    @vasily-v-ryabov да, наверное. Например, при выборе элемента из combo box, появляется диалоговое окно (типа, при выборе этого элемента произойдёт что-то, вы уверены? или типа того). И вот пока выбор в диалоговом окне не сделан, элемент в combo box не считается выбранным. И вот тут и происходит зависание. Это есть не только с combo box, такое возможно и с другими элементами.
    Vasily Ryabov
    @vasily-v-ryabov
    @eratheo Понятно. Значит, надо имплементить. Но надо подумать, как лучше сделать в самой библиотеке. Предлагаю завести issue, я помечу его как enhancement. Попадёт оно только в следующий мажорный релиз, дату которого сложно предсказать. Так что, если это срочно, реализуйте как сможете. Если есть возможность поделиться кодом, я могу обещать пулл реквест оперативно ревьюить. Ну, или просто в issue можно monkey patch кинуть, если неохота полностью контрибутить фичу. Как дойдут руки, доделаем.
    Aleksey Semenenko
    @alex.aka.wild_gitlab

    @vasily-v-ryabov добрый день, подскажите пожалуйста по find_element. Хочу найти элемент на странице при помощи

    pywinauto.findwindows.find_elements(backend="uia", auto_id="NextStepButtonId", control_type="Button")

    Но получаю пустой список, при этом если тоже самое переписать в формате

    app.child_window(backend="uia", auto_id="NextStepButtonId", control_type="Button")

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

    Vasily Ryabov
    @vasily-v-ryabov
    @alex.aka.wild_gitlab день добрый. find_elements не рекомендуем использовать, потому что это низкоуровневая функция, в которую легко недодать какие-то параметры, которые верхнеуровневые объекты передают. Если проблема только в том, что есть два+ элемента с одинаковыми свойствами, то просто добавляете в критерий поиска found_index=0 или found_index=1. В следующем мажорном релизе будет метод find_all(), а пока вот так...
    Aleksey Semenenko
    @alex.aka.wild_gitlab
    @vasily-v-ryabov нет, проблема не в том, что несколько элементов. Тут как раз всё хорошо, индекс и список мои друзья. Тут вопрос в другом, что есть многостраничное приложение, в котором элементы управления повторяются из страницы в страницу. Например кнопки вперед и назад. Но каждая страница имеет своё имя поэтому для общих элементов хотелось добавить нахождение без привязки к какому-либо окну. Сделать некое подобие page object для .Net приложения
    Vasily Ryabov
    @vasily-v-ryabov
    Ну, вообще, если страницы сменяют друг друга, а не одновременно находятся на экране, то WindowSpecification объект прекрасно ре-юзается. Если это привязка к разным процессам, то при ре-коннекте тоже можно ре-юзать ту же спецификацию. Остальное вроде должно решаться средствами самого питона, включая наследование page объектов. Если pywinauto тут может ещё чем-то помочь и это можно сформулировать в псевдо-коде, то можно обсудить и реализацию. Пока я не до конца понимаю сам сценарий.
    Mark Rudenko
    @Krotovod
    Добрый день. При работе с pywinauto обнаружил, что при выделении текста методом wind.type_keys('^a') работает при запуске кода с языковой панелью на английском, но не на русском. При изменении языка по ходу выполнения кода, текст не выделяется. Видел всего пару сообщений, но решения не нашел.
    Vasily Ryabov
    @vasily-v-ryabov
    @Krotovod добрый день. Если это EditWrapper (wind.wrapper_object()), то у него есть метод .select(start, end).
    Mark Rudenko
    @Krotovod
    @vasily-v-ryabov я просто ввожу текст в поле, но перед этим хочу стереть предыдущий текст. Так как приложение не имеет дерева (Viber) мне приходится использовать метод .window().type_keys(). И в этом случае возникает проблема с сочетаем клавиш Ctrl+a. Если язык выбран английский -текст выделяется, если русский - нет.
    Vasily Ryabov
    @vasily-v-ryabov
    @Krotovod зная, как выглядит десктопная иерархия окон у большинства современных мессенджеров, я бы посоветовал использовать их HTTP API, благо есть питонные обёртки над ними. Например, https://developers.viber.com/docs/api/python-bot-api/
    atom4git
    @atom4git

    Добрый день! Пытаюсь сделать помощник системного администратора (аля консоль с подключением к удаленным рабочим столам пользователей) Не получается найти поле ввода ID AnyDesk. (как я не пытался поле Edit видит только свой ID). Прекрасная утилита Swapy крашится при попытке подключиться к AnyDesk. пытался получить поле Edit перебором вида

    edit = window.Edit4

    Вот код которым пытаюсь "найти" окно ввода

    from pywinauto.application import Application
    
    app = Application(backend="uia").connect(title=u'AnyDesk')
    dlg_spec = app['AnyDesk']['Новое соединение']
    app.AnyDeskDialog.print_control_identifiers()

    Подскажите куда копать... Опыта в Python у меня мало (не судите строго), постараюсь компенсировать усидчивостью

    Vasily Ryabov
    @vasily-v-ryabov
    @atom4git добрый день. Если вы попытаетесь прямо с локальной машины получить UI элементы из удалённого рабочего стола, то у вас ничего не получится. Remote Desktop и другие подобные инструменты просто не прокидывают эту информацию. Кое-какая инфа про удалённые запуски GUI automation скриптов внутри RDP (или AnyDesk) окна собрана вот здесь: Remote Execution Guide.
    atom4git
    @atom4git
    Нет, я пытаюсь с помощью pywinauto вписать в программу AnyDesk ID и пароль ПК которому полключаюсь по средствам AnyDesk. Но не могу понять как мне получить поле ID в этой программе
    Vasily Ryabov
    @vasily-v-ryabov
    Можете сделать скриншот из Inspect.exe? Это тула из Windows SDK, но можно и отдельно её скачать (ссылка есть в Getting Started Guide). Только переключиться надо в режим MS UI Automation и нажать "Show hierarchy".
    Vasily Ryabov
    @vasily-v-ryabov
    Или более простая альтернатива: https://github.com/pywinauto/py_inspect
    atom4git
    @atom4git
    я так и не понял как эта альтернатива рботает (не удалось запустить )... Возможно где то есть эта программа уже собраная?
    atom4git
    @atom4git

    Можете сделать скриншот из Inspect.exe? Это тула из Windows SDK, но можно и отдельно её скачать (ссылка есть в Getting Started Guide). Только переключиться надо в режим MS UI Automation и нажать "Show hierarchy".

    не нашел в Inspect.exe режим MS UI Automation и нажать "Show hierarchy".

    фото из Inspect.exe

    Vasily Ryabov
    @vasily-v-ryabov
    А, ну да, русскоязычная винда. Но нужный режим уже включен.
    Осталось только на нужное поле навести курсор или выбрать его в иерархии.
    Vasily Ryabov
    @vasily-v-ryabov
    Думаю, вот так должен найти: app.AnyDeskDialog.child_window(control_type="Edit").wrapper_object() Если скажет ambiguous error, то добавить found_index=0 или нужный индекс.
    atom4git
    @atom4git
    А, ну да, русскоязычная винда. Но нужный режим уже включен.
    Вот эта панель должна содержать поле для ввода ID
    atom4git
    @atom4git

    Думаю, вот так должен найти: app.AnyDeskDialog.child_window(control_type="Edit").wrapper_object() Если скажет ambiguous error, то добавить found_index=0 или нужный индекс.

    entry = app.AnyDeskDialog.child_window(control_type="Edit").wrapper_object()
    entry.double_click_input()

    Добавил данные строки в код (как итог он выделяет строки в моем коде...) что то пошло не так )

    atom4git
    @atom4git

    я понял скрипт не переключается на нужное окно... Но это вопрос номер два.

    А по первому: при индексе > 0 выдает вот что:

    pywinauto.findwindows.ElementNotFoundError: found_index is specified as 1, but no windows found

    При этом пытается выделить поле ввода (но к сожалению не то что нужно)...

    Vasily Ryabov
    @vasily-v-ryabov
    Так очевидно же, что поле ввода - одно. Если указать второе (found_index=1), то его и нету. Всё правильно.
    Получается, Inspect.exe не видит нужного поля. Это вопрос уже к разработчикам AnyDesk, полагаю. Или оно реально на удалённой машине находится, и тогда часть скриптов надо туда копировать и запускать.
    Возможно, после активации окна (на панели сделать .set_focus()) нужное поле появится (динамически создастся?).
    atom4git
    @atom4git

    Вот вид окна
    Нам/мне) нужно получить поле "Введите AnyDesk ID или псевдоним"
    Вот код:

    from pywinauto.application import Application
    app = Application(backend="uia").connect(title=u'AnyDesk')
    dlg_spec = app['AnyDesk']['Новое соединение']
    dlg_spec.set_focus()
    dlg_spec.wait('visible')
    entry = app.AnyDeskDialog.child_window(control_type="Edit", found_index=0).wrapper_object()
    entry.double_click_input()

    Если просто активировать окно программы (без python-а) и начать вводить символы то они будут вводиться в поле сверху...
    Может с этим что-то можно пришаманить?

    Vasily Ryabov
    @vasily-v-ryabov
    Ну, entry.set_edit_text("...") или entry.set_value("...") или entry.type_keys("...") (если первые два не сработают).
    Vasily Ryabov
    @vasily-v-ryabov

    Скачал AnyDesk, попробовал. Ни один edit box из двух не виден. Этот единственный edit box - это ID локальной машины.
    Конечно, через .type_keys("machine-name{ENTER}") можно подключиться, но как там дальше - скорее всего будут проблемы. Раз уже на первых страниц многие даже кнопки не видны, то дальше и того меньше будет. Софтина явно на каких-то браузерных элементах построена (а для них по умолчанию accessibility отключена).

    Не совсем понимаю, зачем такие пляски с бубном и в чём всё-таки всемогуторная идея консоли? Если просто команду выполнить, то чем мешает подключение по WMI или SSH? Ну да, GUI запустить и управлять на удалённой машине не получится, но это реально надо? Тогда почитайте Remote Execution Guide ещё раз внимательнее.

    atom4git
    @atom4git
    Зачем? Честно сказать интересно сделать что то подобное), загорелось... Да и полезность для себя иногда ощущаю.
    Через .type_keys("machine-name{ENTER}") так и не заработало, к сожалению. Есть еще варианты?
    Mark Rudenko
    @Krotovod
    @atom4git , при использовании метода .type_keys() вылазит ошибка или без ошибки не вводит текст?
    atom4git
    @atom4git

    @Krotovod , есть ошибка при свернутом окне. При развернутом ошибок нету, так же как нету и ввода (я думаю что он (скрипт) опять таки пытается вводить в область с моим ID)

    from pywinauto.application import Application
    app = Application(backend="uia").connect(title=u'AnyDesk')
    dlg_spec = app['AnyDesk']['Новое соединение']
    dlg_spec.set_focus()
    dlg_spec.wait('visible')
    dlg_spec.type_keys("1111{ENTER}")

    вот собственно код... Может я диалоговое окно не то выбираю?

    Mark Rudenko
    @Krotovod
    @atom4git , может быть. Попробуйте ввести какой-либо текст в нужное поле и после этого использовать метод '.print_control_identifiers()'. По-идее введенный текст должен будет отобразиться в древе процессов и можно более точно определить элемент для ввода.
    На счет свернутого окна - я сталкивался с тем, что при свернутом окне возможен ввод текста, но нажатия кнопок не происходит. Как это обойти - не придумал, просто вывожу на определенном этапе приложение вывожу на передний план.
    Vasily Ryabov
    @vasily-v-ryabov

    Можно для главного окна попробовать .type_keys(...). Это последнее средство. Конечно, при свёрнутом окне это не сработает. Кстати, .type_keys(...) в любом случае делает .set_focus(), что должно развернуть окно автоматически перед вводом.

    Моё мнение - это проект чисто для развлечения, потому что много подводных камней и тулов должно быть много уже существующих похожих и использующих более подходящие технологии и протоколы (тот же WMI).

    Oleg
    @eratheo
    добрый день. После перерыва решил вернуться к экспериментам с pywinauto. Появились новые вопросы. Мой workflow выглядит примерно так - я запускаю приложение, появляется некий splash screen на какое-то время. Далее возможны варианты - 1. если при предыдущем запуске было выбрано много данных, то появится диалог хочу ли я их всех загрузить, а далее открытие основного окна приложения. 2. если данных было не много, то диалог не появляется, а сразу идёт открытие основного окна приложения. Запускается всё небыстро, поэтому постоянно натыкаюсь на timeout error. Решил поиграться с параметром timeout в wait(), работает, но время запуска зависит от многих параметров и при одних обстоятельствах 30 секунд много, а при других мало. Это проблема №1. Второй вопрос - как решить момент с появлением или непоявлением диалогового окна. Я пробовал решать через if app.window(title='Confirm').exists():, но тут снова timeout Появляется. В общем, я запутался. Возможно есть какое-то логично решение, которого я не вижу. Спасибо.
    Oleg
    @eratheo
    Хммм... Вроде бі, решилось с помощью app.wait_cpu_usage_lower(threshold=5). Но пока неясно, как это работает ))
    Vasily Ryabov
    @vasily-v-ryabov
    Это работает, потому что пока грузятся данные, жрется проц. А пока диалог ждёт нажатия кнопки, проц не жрется. Потому что иначе процы меняли бы каждый месяц от перегрева, если бы ось по-другому была реализована. :)
    Даже не столько и не только ось, сколько железо в целом. Слава прерываниям.
    Просто ждать жмяка кнопки - это 99,9% всего времени.
    Mark Rudenko
    @Krotovod
    @vasily-v-ryabov Есть вопрос: каким то образом можно определить текущий вид курсора (стрелка, рука, пр)?
    Yaroslav
    @2yar2
    Всем привет!