Как заставить Python и AutoIT работать вместе, используя win32com: что случилось с этими дескрипторами окна? - PullRequest
10 голосов
/ 13 января 2012

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

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

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

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

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

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

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

Пример:

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

Как правило, returnWindowTitle и knownWindowTitle не совпадают какreturnWindowTitle всегда кажется "0".что здесь происходит?

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

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

РЕДАКТИРОВАТЬ : я забыл упомянуть, что строки Unicode на самом деле соответствуют шестнадцатеричным числам, которые я получаю при выводе переменной handle в AutoIt.

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

EDIT : некоторые испытания, основанные на предложениях Мата:

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 чисел / дескриптором / и т. Д.).Просто мне повезло, что они не поместили эту функцию в AutoItX (COM dll).Итак, если я действительно хочу работать с этим, мне придется попытаться выяснить, как вернуть любой объект, на который он указывает адресом base 16, и затем передать его правильным способом в AutoItX?Я, наверное, звучу очень растерянно, потому что все это сейчас не очень ясно в моей голове.

Ответы [ 2 ]

2 голосов
/ 22 июня 2012

Ради поиска выложу найденное решение.

Вот код:

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 голосов
/ 19 января 2012

Тип дескрипторов окна - строка. Причина в том, что 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 достаточно «умен», чтобы понять, что делать в большинстве случаев, может быть, библиотека не совсем.

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