Подтвердить что ты не робот

Как заставить Python и AutoIT работать вместе с помощью win32com: что с этими окнами?

У меня есть программа с интерфейсом GUI, чья первоначальная настройка мне нужно сделать вручную. AutoIt был чрезвычайно полезен для этого до сих пор, поскольку он обеспечивает очень простые способы работы даже со сложными для доступа объектами графического интерфейса (выпадающие списки, меню "наведите курсор" и т.д.).

Тем не менее, script, который мне понадобится, чтобы выполнить настройку программы, должен быть передан большой массив/список переменных - существует множество различных параметров, которые необходимо изменить.

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

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

С этой целью я пытался использовать Python вместе с библиотекой win32com для взаимодействия с AutoIt. Кажется, что все хорошо работает - до тех пор, пока я ссылаюсь на окна/меню/объекты по строковым названиям, а не на их (память?). Это проблематично, так как мои скрипты настройки могут работать параллельно, одновременно устанавливая два или более отдельных файла. Если это так, при открытии окна с заголовком "Открыть файл..." в каждом файле в то же время могут запутать вещи.

Очевидным способом обойти это в AutoIt является работа с "ручками" рассматриваемых объектов, которые, я считаю, являются адресами памяти какого-то типа, а не их названиями строк. Я предполагаю, что это адреса памяти в качестве инструмента AutoIt Window Info, когда указана на конкретный параметр Window/GUI object, перечисляет шестнадцатеричное число как значение дескриптора объекта.

В AutoIt есть набор функций, которые обрабатывают дескрипторы окон, меню и т.д. Они реализованы в DLL AutoIt COM, но я не смог заставить их работать на Python. Функции handle возвращают объект unicode в Python, а не в шестнадцатеричную строку, как в AutoIt. Я думаю, что это причина, почему функции, которые затем пытаются использовать этот "дескриптор" в Python, не работают.

Пример:

autoIt = win32com.client.Dispatch("AutoItX3.Control")
windowHandle = autoIt.WinGetHandle(knownWindowTitle)
returnedWindowTitle = autoIt.WinGetTitle(windowHandle)

Обычно возвращаемые именаWindowTitle и knownWindowTitle не совпадают, поскольку returnWindowTitle всегда кажется "0". шляпа здесь?

Существуют ли другие способы для вызова пользовательских функций AutoIt помимо использования win32com, командной строки или использования ключевого файла AutoIt?

Спасибо за вашу помощь.

EDIT. Я забыл упомянуть, что строки unicode действительно соответствуют шестнадцатеричным числам, которые я получаю, когда распечатываю переменную дескриптора в AutoIt.

Например, в Python переменная handle при распечатке дает мне u'000C0326 '. В AutoIt он дает мне "0x000C0326".

РЕДАКТИРОВАТЬ: некоторые испытания, основанные на предложениях Mat:

In: autoIt = win32com.client.Dispatch("AutoItX3.Control")
In: mainWindowTitle = "Untitled"
In: mainWindowHandle = autoIt.WinGetHandle(mainWindowTitle)
In: mainWindowHandle
Out: u'000204AC'
In: testHandle = int(mainWindowHandle, 16)
In: testHandle
Out: 132268
In: autoIt.WinGetTitle(testHandle)
Out: u'0'

EDIT. Я узнал тип объекта дескриптора окна: это объект Microsoft HWND. Функция AutoIt имеет функцию, которая может "преобразовать" базовый номер 16 в объект HWND (т.е. Найти объект HWND с этой базой 16 памяти/дескриптором/etc). Просто мне повезло, что они не поместили эту функцию в AutoItX (COM-dll). Итак, если я действительно хочу работать с этим, мне нужно попытаться выяснить, как вернуть любой объект, на который указывает базовый 16-й адрес, а затем передать его в AutoItX правильно. Я, наверное, очень смущен, потому что все это сейчас не очень ясно в моей голове.

4b9b3361

Ответ 1

Для поиска я отправлю решение, которое я нашел.

Здесь код:

In: autoIt = win32com.client.Dispatch("AutoItX3.Control")
In: autoIt.AutoItSetOption("WinTitleMatchMode", 4)
In: mainWindowTitle = "Untitled"
In: mainWindowHandle = autoIt.WinGetHandle(mainWindowTitle)
In: mainWindowHandle
Out: u'000204AC'
In: testHandle = "[HANDLE:%s]" % mainWindowHandle
In: autoIt.WinGetTitle(testHandle)
Out: u'Untitled - Notepad'

autoIt.AutoItSetOption("WinTitleMatchMode", 4) указывает autoit на использование расширенного соответствия заголовков, что позволяет нам указывать дескриптор окна с строкой [HANDLE:000204AC].

Здесь нет необходимости в действительном дескрипторе окна.

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

Ответ 2

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

Функция AutoIt имеет функцию, которая может "преобразовать" базовое число 16 в объект HWND.

Точно! Это ключ. AutoIt делает это за вас. Вы пытаетесь преобразовать дескриптор в что-то полезное для AutoIt, но AutoIt уже может использовать эти дескрипторы, хранящиеся в виде строк.

Ваш тест должен быть:

In: autoIt = win32com.client.Dispatch("AutoItX3.Control")
In: mainWindowTitle = "Untitled"
In: mainWindowHandle = autoIt.WinGetHandle(mainWindowTitle)
In: mainWindowHandle
Out: u'000204AC'
In: autoIt.WinGetTitle(mainWindowHandle)
Out: u'Untitled - Notepad'

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