@Andrew_Lays

Как заставить работать SendKeys через RDP?

Есть удалённый Windows сервер, на нём стоит программа PROGRAM, также установлен Open Server, с открытым доступом извне. Open Server я установил, чтобы запускать на сервере нужные python-скрипты просто стучась извне по IP-адресу сервера, для этих целей написан php-скрипт, который при вызове запускает нужный python-скрипт. Итого, чтобы запустить python-скрипт на сервере, я запускаю скрипт server.domain/script.php. Дальше python-скрипт должен, к примеру, запустить блокнот и напечатать в нём текст, для этого использую такой python-код:
import SendKeys
from pywinauto.application import Application

app = Application().Start('notepad')

SendKeys.SendKeys('some text')

Потом, когда я захожу на сервер я вижу только открытое окно блокнота, пустое, без текста.
Если я перезапущу этот же python-скрипт на сервере через консоль, то откроется блокнот и в него напечатается текст "some text". В результате гугления и тестов я понял, что не работает набор текста и управление мышью через RDP для обеспечения безопасности. Так же нашёл несколько советов использовать SendInput и SendMessage, но не смог применить их к python. Как напечатать текст удалённо, может снять ограничения системы безопасности?
  • Вопрос задан
  • 1166 просмотров
Пригласить эксперта
Ответы на вопрос 2
vasily-v-ryabov
@vasily-v-ryabov
Python, UI Automation, pywinauto
Для сохранения активного десктопа можно использовать VNC (например, мы пользуем TightVNC в качестве клиента и сервера) вместо RDP. Только, если всё же зашли по RDP, то потом надо перезагрузить сервер, чтобы VNC сессия нормально работала. А ещё скрипт на сервере нельзя запускать как сервис (из сервиса активный GUI context недоступен). Для VNC, возможно, ещё потребуется обновить видеодрова, т.к. он отображает реальный выход с видеокарты в отличие от виртуального RDP.

Что касается pywinauto, то там SendKeys как раз использует системную функцию SendInput. В ветке UIA на гитхабе (релиз запланирован на июль) уже есть метод send_chars(...), который посылает WM_CHAR через SendMessage (работает для свёрнутого окна и при залоченной винде). Но этот метод нужно использовать для конкретного окна, а не просто глобально для системы. Пример:
app = Application().start('notepad.exe')
app.UntitledNotepad.Edit.send_chars('Hello World!') # не нужен GUI context
app.UntitledNotepad.Edit.type_keys('\nTyping to the active window...', with_newlines=True) # нужен GUI context

Вызов метода для конкретного контрола ещё и автоматически ждёт, когда окно/контрол реально появится и будет готов к вводу.
Ответ написан
FantomNotaBene
@FantomNotaBene
Программист, трейсер
ожидание сделайте между строкой где запускается приложение и SendKeys()
from time import sleep
...
sleep(3)
...
думается мне, все работает как надо, но, как сказали выше, текст отправляется в текущее активное окно, а на момент когда передаются нажатия клавиш, блокнот просто не успевает открыться и оказаться в фокусе
а нажатия клавиш передаются, полагаю, пустому рабочему столу, где, разумеется, не вызывают никакой реакции на себя
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы