Autoit сделать окно активным

Обновлено: 19.05.2024

Проблема: запуск AutoIT программы в блокированном сеансе Windows

Удивительно, проработав несколько лет мой скрипт AutoIT для автоматизации сборки проекта из MG-SOFT Visual MIB Builder 9 в один день перестал работать и файлы перестали собираться. При активном рабочем столе однако все работало. Также и при подключении по удаленному доступу к рабочему столу — скрипты работают пока окно не свернуто и активно.

Предыстория

MG-SOFT Visual MIB Builder 9 у нас лицензионный потому мы его до сих пор используем для работы, но вот вручную экспортировать готовые MIB и вручную же их проверять это рутинно и скучно, особенно при наличии сервера автоматизации Jenkins.

Я пользуясь привилегией лени над палкой, написал на AutoIT 3 автоматизатор, который кликал куда надо за меня и на вывод кидал бы мне список ошибок, если они есть. Если сборка падает я сразу в письме получаю список ошибок в проекте по каждому файлу.

Чтобы Jenkins мог выполнять задачи в которых задействованы графические приложения я создал удаленный сборщик Jenkins (далее jenkins-gui-win-slave) на этой же машине. На ПК создан отдельный пользователь ci-server в сеансе которого при входе в систему запускается из автостарта скрипт запуска агента Jenkins. Подключается агент через Java WebStart, JNLP. Чтобы jenkins-gui-win-slave стартовал для пользователя ci-server настроен автоматический вход в систему при старте ПК, в автозапуске лежит скрипт запуска jenkins-gui-win-slave, а в планировщике заданий Windows есть задача "при входе" выполнить "скрипт блокировки сеанса пользователя" — это позволяет сразу после входа заблокировать от нежелательных посетителей сервера сеанс ci-server.

В итоге при старте системы происходит автоматический вход для пользователя `ci-server`, запуск агента `jenkins-gui-win-slave`, блокирование сеанса пользователя `ci-server`.

Проблема

Программы при блокировке сеанса Windows помещает приложения в изолированный сеанс Session 0 для обеспечения безопасности, т.к. считается, что активность в графическом приложении во время блокировки должна отсутствовать. Это накладывает ограничения, и часть оконных функций тогда не работает.

В отношении к AutoIT это приводит к тому, что невозможно дождаться события активации окна WinWaitActive, WinActive всегда возвращает ошибку, невозможно управлять мышью, невозможно переключить активное окно, потому и функции работающие в контексте активного окна перестают работать, например Send.

Решение

Есть два решения: без изменения кода и с изменением кода.

1. Без изменения кода

Установить виртуальную машину, в нее поставить Windows, агент Jenkins и нужное для сборки ПО. Причем для Windows 7 Pro можно использовать легально Windows XP Mode — получаете виртуалку с XP и на ней все гоняете. Или используйте другое ПО для виртуализации, например VirtualBox, туда придется ставить ОС отдельно. Для виртуалки нужно настроить IP адрес, чтобы агент Jenkins мог подключаться к мастер серверу Jenkins. Для XP Mode IP адреса также можно настроить.

В виртуалке можно использовать пользователя по умолчанию.

В виртуалке в папку Автозапуск поместить скрипт командной строки (.bat\.cmd) для запуска агента Jenkins.

Пример скрипт запуска агента Jenkins:

rem Runs jenkins-gui-win-slave to work with GUI builds

:: jenkins-master-addr — адрес MASTER сервера jenkins

:: secret_string — ключ доступа к серверу для агента, см. в настройках агента на сервере Jenkins

Отключить скринсервер, отключить функцию "начитать с блокировки экрана". Настроить автоматический вход для пользователя без пароля при старте системы.

Далее настроить автозапуск виртуалки.

В этом случае даже при блокировке сеанса пользователя в виртуальной машине сеанс будет не заблокирован. Естественно вы несете расходы на виртуалку — это обосновано, когда у вас много скриптов и их переделка и отладка займет много времени или у вас приложения которые работают не так как обычные и им нужно обязательно активное окно для работы с его контролами.

2. С изменением кода

Я пошел этим путем, т.к. у меня только одна такая задача была.

Чтобы обойти ограничения режима блокировки, нужно:

  1. отказаться от тех функций, что работают с активными окнами или заменить их на альтернативные.
  2. Отказаться от движения мышью MouseMove, MouseClick и т.п.
  3. Заменять функцию Send на ControlSend или ControlClick.

Примечание: скрипты записанные Au3Record используют как раз функции не работающие в режиме блокировки сеанса.

С приложением работаем так будто бы окна уже активны в момент обращения.

Заменяем:

; Делаем окно активным и жмем кнопку
if (WinActivate($windowName)) Then
; Нажать кнопку в окне
ControlClick($windowName, $buttonName, "")
EndIf

; Попытаемся сделать активным окно. При блокировке сеанса может не срабатывать, но нам и не важно
WinActivate($windowName)
; Нажимаем кнопку
ControlClick($windowName, $buttonName, "")
; или ControlSend($windowName, "", $buttonClass, "")

В данном случае можно работать с существующей инфраструктурой на сервере, но не все скрипты могут быть так однозначно трансформировать. Некоторые приложения могут быть не приспособлены для такого взаимодействия, тогда придется прибегнуть к варианту 1.

Autoit сделать окно активным

Активирует указанное окно (передаёт ему фокус).

WinActivate ( "title" [, "text" ] )

title Заголовок/дескриптор/класс окна. См. заголовки и текст окон (расширенные).
text [необязательный] Текст окна.

Успех:Возвращает дескриптор окна.
Ошибка:Возвращает 0, если указанное окно не найдено или не может быть активировано.

Можно использовать функцию WinActive () , чтобы узнать об успехе (или неудаче) функции WinActivate () . Если несколько окон соответствуют критерию, будет активировано самое недавнее активное окно. WinActivate () может работать со свёрнутыми окнами. Обратите внимание, что окна с атрибутом "Всегда поверх всех окон" по-прежнему будут отображаться поверх активированного окна.

@extended содержит дополнительную информацию о выполнении процесса активации (0 - окно не найдено, 1 - окно было активно, 2 - окно было неактивно).

; Запуск блокнота свёрнутым
Run ( 'notepad.exe' , '' , @SW_MINIMIZE )

Сделать активным окно и послать в него текст атомарно

Задача и вопрос очень простые:
Выполняется поиск окна по заголовку, окно активируется и в него посылается текст:


Проблема в том что на рабочем столе во время выполнения скрипта могут "появляться" активные окна, тогда текст посылается в них, очевидно что после активации нужного мне окна одно из всплывающих окон "делает себя активным" что недопустимо.

Как можно сделать окно активным и послать в него текст так чтобы во время выполнения этих двух операций никакое другое окно не могло стать активным? Так чтобы операция "Сделать активным окно и послать в него текст" была "атомарной"?

Как сделать конкретное окно активным

Я хочу знать, как сделать окно (например, Google Chrome, Блокнот) активным, как если бы я щелкнул по нему курсором. Я искал в Google, но ничего не нашел.

Может кто-нибудь сказать мне, какую функцию использовать и какие параметры она использует. Вот что я уже пробовал использовать

Но WinWaitActive ждет, пока окно станет активным, вместо того, чтобы активировать его.

Anne Skeitzig 6 Июл 2016 в 23:21

2 ответа

Лучший ответ

WinActivate должен делать то, что вы ищете.

Что вы пытаетесь сделать, так это изменить фокус окна.

Tyler 6 Июл 2016 в 20:24

Если это для определенного элемента управления внутри окна, используйте ControlFocus.

Нажмите на элемент управления, используя AutoIt, если окно присутствует в фоновом режиме или спереди

Я хочу нажать кнопку, которая присутствует в форме EXE файла.

Ниже мой код, который я пробовал.

    Первая строка, WinWaitActive("ABCD") ждет, пока окно ABCD не вступит в фокус. Вторая строка нажимает на кнопку " Отложить" Третья строка запускает один и тот же EXE файл для обработки того же сценария, если это происходит.

Это работает правильно, если окно ABCD фокусируется. Он не работает, если он не находится в фокусе. Как мне решить эту проблему?

спросил(а) 2013-07-16T15:17:00+04:00 8 лет, 2 месяца назад добавить комментарий пожаловаться

Ну, вы должны использовать бесконечный цикл вместо того, чтобы запускать один и тот же скомпилированный скрипт снова и снова. И JonBecher прав, но отсутствует случай, когда окно никогда не становится активным. Таким образом, ваше решение будет:

Это означает, что ваш клик закроет окно, и вы хотите дождаться появления такого же окна в будущем. Иначе ваш полный intenional Run(. ) -call не имеет смысла.

С ControlClick(. ) вам не нужно, чтобы ваше окно было активным или даже видимым.

ответил(а) 2013-07-17T14:31:00+04:00 8 лет, 2 месяца назад добавить комментарий пожаловаться

Используя WinActivate вы можете сделать окно в фокусе.

Это позволит сосредоточиться на окне "ABCD".

ответил(а) 2013-07-16T16:37:00+04:00 8 лет, 2 месяца назад добавить комментарий пожаловаться

если вы отправляете управляющий ключ, то не нужно ждать или фокусироваться на этом окне. он будет обрабатывать. Я пишу этот код для Skype sso, независимо от того, где находится окно. Он работает, если окно сведено к минимуму.

WinActivate -Autohotkey

Если окно свёрнуто, оно будет автоматически восстановлено перед активацией.

Шесть попыток активировать целевое окно будет сделано в течение 60 мс. Так что обычно нет необходимости использовать после WinActivate команду WinWaitActive.

Если активное в данный момент окно соответствует параметрам команды, оно будет оставлено активным. Т.е. не будет активировано никакое окно ниже его, даже если оно также совпадает с параметрами. Как общее правило, если несколько окон отвечают заданным критериям, активируется самое верхнее (последнее активное) окно. Вы можете активировать самое нижнее окно (бывшее активным раньше всех остальных) через команду WinActivateBottom.

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

AutoIT WinWaitActive не активирует это окно

Я хочу получить пиксельный цвет из игры и отреагировать. Итак, у меня есть это sript:

Главный сценарий должен быть активным до того, как окно будет активным, и только затем следует попробовать GetPixelColor, но это никогда не произойдет, независимо от того, что я делаю, я пробовал WindowActivate, но результата нет.

а) - Что я делаю неправильно? Или может быть другой способ проверить, включено ли в настоящее время окно?

Поэтому на данный момент я запускаю скрипт отключен, и когда я активирую окно вручную, я нажимаю F11 для включения.

b) - PixelGetColor работает только в том случае, если игра запущена в Windowed режиме, если результат полноэкранного режима непредсказуем. Есть ли способ заставить PixelGetColor работать в полноэкранном режиме.

Я попытался запустить игры x32, x64, DX9 и DX11 в разных комбинациях. Полноэкранный результат просто неверен.

ДОБАВЛЕНО:

Теперь, когда выглядит так, и это работает :) Спасибо Xenobeologist .

а) теперь решается

б) до сих пор не решена. Еще одна вещь, тема этого вопроса не говорит ничего об этом вопросе, должна добавить информацию об этом в тему или лучше начать новый поток? а) был моим главным вопросом, было бы префектом решать б), но я могу жить без него. Насколько я понял, это намного сложнее. Как вы думаете?

Как активировать определенное окно

Я хочу знать, как сделать окно (например, Google Chrome, Notepad) активным, как если бы я нажимал на него с помощью курсора. Я искал в Google, но ничего не нашел.

Может кто-то, пожалуйста, скажите мне, какую функцию использовать и какие параметры он использует. Вот то, что я уже пробовал использовать

Но WinWaitActive ожидает, что окно будет активным, а не активирует его.

WinActivate должен делать то, что вы ищете.

То, что вы пытаетесь сделать, это изменить фокус окна.

Если для определенного элемента управления внутри окна, используйте ControlFocus.

AutoIt скрипты - введение и FAQ

Эта статья появилась на сайте ввиду популярности AutoIt у посетителей форума Автоматической Установки Windows. Статья состоит из двух частей. В первой - введение в AutoIt, целиком взятое из русской справки к AutoIt, которую очень грамотно перевел с английского Валерий Иванов. К сожалению, найти координаты автора не удалось, но хочется верить, что он не возражает против публикации его трудов. Я настоятельно рекомендую загрузить справку и ознакомиться с уроками, из которых вы сразу узнаете, насколько просто автоматизировать установку приложений при помощи AutoIt. Вторая часть статьи представляет собой список часто задаваемых на конференции Oszone вопросов о работе с AutoIt. Ответы, конечно, прилагаются. "Oszone AutoIt FAQ" для вас подготовил Sanja Alone.

Введение в AutoIt

AutoIt v3 - это язык для написания сценариев, напоминающий BASIC. Основным его назначением является автоматизация работ с Windows GUI (графическим интерфейсом пользователя MS Windows). Для выполнения этой сложной задачи предоставляется комбинация испытанных методов, включающих в себя - симуляцию нажатий комбинаций клавиш клавиатуры, перемещения указателя мыши и управления окнами и его визуальными элементами. Как показывает практика, эти "приводные ремни" весьма эффективны для получения работающих решений в ситуациях, когда другие стандартные средства (например, VBScript и SendKeys) оказываются бессильны.

По замыслу AutoIt предполагался быть средством "тиражирования конфигураций" ПК. Но с момента создания третьей версии его возможности могут быть использованы для реализации "кухни" автоматизации - написания сценариев решения различных задач, в том числе и для администрирования системы.

  • Симулировать нажатия комбинаций клавиатуры (поддерживается основная масса раскладок клавиатуры)
  • Симулировать перемещения указателя мыши и нажатия на ее кнопки
  • Перемещать, менять размер и управлять параметрами отображения окон
  • Непосредственно взаимодействовать с "управляющими элементами" (controls) окна (получать/менять надпись, перемещать, отключать, и т.п. действия)
  • Работать с буфером обмена для пересылки его текстового содержания
  • Читать, менять и создавать ключи и значения реестра

Новая версия AutoIt3 распознает общепринятые конструкции и имеет стандартный синтаксис, напоминающий синтаксис VBScript и BASIC, и поддерживает обработку сложных выражений, выполнение собственных функций, проводить циклические и условные вычисления. Помимо этого AutoIt3 приспособлен для всего того, что уже давно используют ветераны-сценаристы.

Как и раньше AutoIt имеет небольшой размер интерпретатора (

100KB), который является самостоятельным и не ссылается на другие, кроме системных .dll библиотек. Он намеренно не делает самостоятельных или скрытых записей в реестре, кроме обязательных и составляющих процесс полной установки. Сценарии могут быть скомпилированы в независимые выполняемые файлы с помощью поставляемого компилятора сценариев - Aut2Exe.

Вместе с интерпретатором модернизируются ActiveX и DLL версия AutoIt, которые называются AutoItX3. Эта библиотека представляет собой объединенный композит (COM и стандартная DLL библиотека в одном модуле). AutoItX3 позволяет добавлять уникальные возможности AutoIt в написанные Вами приложения на других языках программирования!

И, наконец, самым знаменательным является тот факт, что AutoIt остался бесплатным. Однако, если Вы имеете возможность поддержать этот проект ценой собственного времени, деньгами или иными усилиями, то все виды пожертвований принимаются на домашней странице AutoIt.

Oszone AutoIt FAQ

Читайте руководство к AutoIt - многое прояснится :) Нижеизложенное - это что-то вроде краткой справки и FAQ по совместительству.

Запуск приложений
  1. Обычный запуск

Полный список макросов смотрите в разделе руководства "Macro Reference".

Системные переменные
  1. В принципе, макросы дублируют большинство системных переменных, но не все. Добраться напрямую к их значениям можно с пом. ф-ции EnvGet, например:
EnvGet("SYSTEMDRIVE")

Создать сист. переменную также можно используя ф-цию EnvSet("envvariable"[,"value"]), но она будет существовать только до выхода из текущего скрипта.

Ввод данных / работа с элементами управления
  1. Посылка символов в активный элемент активного окна

Проверьте, чтобы текстовый файлик скрипта (au3) был в ANSI (Win-1251) кодировке.

По идее, сначала нужно эту кнопку сделать видимой - ControlShow("title","text",controlID), но, довольно часто после применения этой ф-ции, клик на кнопке при помощи ControlClick("title","text",controlID) не проходит. В этом сл., спасением станет MouseClick("left",x,y,1).

Как точно попасть MouseClick-ом в нужную кнопку не зная разрешения экрана.

При написании скрипта используйте привязку координат к клиентской части активного окна. Т.е., когда Вы (используя "AutoIt Window Info") смотрите координаты кнопки, выставьте Options -> Coord Mode -> Client. А в скрипте (перед MouseClock-ом) задайте:

; 1 - привязка к левому верхнему углу экрана (по ум.)
; 0 - привязка к активному окну
; 2 - привязка к клиентской части активного окна (все то, что ниже заголовка)
Opt("MouseCoordMode",2)
;фрагмент информационного окна AutoIt Window Info:
Control ID: 1
ClassNameNN: Button2
Text: &Next >
Работа с ini-файлами

  1. У AutoIt-а есть пять ф-ций для этих целей:

Импорт данных из reg-файла в реестр
  1. С помощью функции RunWait и штатной утилиты regedit.exe
Предотвращение возможности множественного запуска скрипта
If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)
Отлов "случайных" окон
  1. Если место появления окна известно
;ждем не более 2 секунд. Будет окно - отработаем с ним, нет - просто пойдем дальше
If WinWait("Installer Language","",2) Then
WinActivate("Installer Language")
WinWaitActive("Installer Language")
Send("")
EndIf

Действующий пример использования AdlibEnable (а также вызова своей ф-ции при выходе из скрипта Opt("OnExitFunc","MyExit")) можете посмотреть в моем скрипте для установки переводчика Pragma.

Читайте также: