Как автоматизировать ввод с клавиатуры пользовательского интерфейса? Pywin32 PostMessage против SendKeys Powershell - PullRequest
0 голосов
/ 06 мая 2020

Мотивация: Я использую программное обеспечение, которое не имеет API для взаимодействия с ... У меня нет альтернативы, и мне нужно открыть программное обеспечение, отправить простую последовательность клавиш, а затем закрыть .. Снова и снова, поэтому я хочу автоматизировать этот процесс.

Цель: Отправить комбинации вводов с клавиатуры в неактивное окно.

Прогресс: Я написал сценарий PowerShell, который открывает, отправляет ключи, ждет, а затем завершает процесс, но он работает только в активном окне. Часть кода PowerShell выглядит следующим образом.

$appProcess = Start-Process -FilePath $path -PassThru 
$wshell = New-Object -ComObject wscript.shell;
$wshell.AppActivate($appProcess.Id)
$wshell.SendKeys('%(E)E')
Stop-Process $appProcess -Force

Работает, но только в активном окне (windows выходит наверх). Я хочу запустить автоматизацию окна в фоновом режиме. Я нашел статью , которая указывает мне использовать PostMessage в Win32 API. Поскольку в большей части моего кода используется python, я решил перейти с powershell на pywin32.

Проблема: Я не могу получить PostMessage для отправки ключа в правый обработчик. Я видел в этой статье , что мне может понадобиться найти точное окно, но я до сих пор не понимаю, как это сделать. В PowerShell я могу напрямую отправлять ключи через $ wshell.AppActivate ($ appProcess.Id) .

hwndMain = win32gui.FindWindow(None, winname)
hwndChild = win32gui.GetWindow(hwndMain, win32con.GW_CHILD)
temp = win32api.PostMessage(hwndChild, win32con.WM_KEYDOWN, 0x45, 0)
# temp came out as None

Вопрос: Есть ли способ сделать это в pywin32 / Win32 API?


Изменить: (8 мая 2020 г.) Да, я слышали, что использование SendKeys ненадежно, но поскольку нет альтернативы таким вопросам, как этот, о SO, как кто-то должен научиться «правильному пути»? Если вы считаете, что есть альтернатива, все будут рады увидеть решение в действии. Пожалуйста, предложите отредактировать мой пост, чтобы улучшить качество вопроса, а не сокращать его.

1 Ответ

0 голосов
/ 07 мая 2020

Time a go Я разработал утилиту SendMessage , которая позволяет отправлять сообщения другим процессам или Windows через WIN32 API. Я обнаружил, что не могу отправить сообщение в неактивное окно, поэтому искал способ активировать окно. После нескольких тестов я обнаружил трюк, который позволяет мне «повторно активировать» окно:

При разработке этой программы возникла проблема: элементы в самом верхнем меню Блокнота нельзя выбрать, если окно не был активен. Я провел несколько тестов и обнаружил, что этот момент зависит от отношения, которое окно cmd.exe имеет (имеет?) С другим окном и конкретной программой в другом окне. Например, в случае аксессуара «Калькулятор Windows», его пункты меню могут быть выбраны, когда окно не активно, и даже когда оно свернуто! Я попытался разработать способ активировать другое окно из cmd.exe, используя только сообщения, определенные системой. Я провел несколько тестов с использованием различных комбинаций сообщений WM_ACTIVATE, WM_CANCELMODE, WM_ENABLE, WM_ACTIVATEAPP, WM_SETFOCUS и WM_KILLFOCUS, но безуспешно. К счастью, элементы системного меню любого окна можно выбрать из другого окна, и после SC_RESTORE восстановленное окно остается активным; это поведение позволяет активировать Блокнот и другие windows из cmd.exe с помощью процедуры Minimize / Restore.

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

...