Беда с автоматизацией Windows RDP через консоль - PullRequest
0 голосов
/ 13 мая 2019

Краткое описание моей проблемы:

1.Мое задание Jenkins требуется для установления соединения RDP с другим компьютером для выполнения некоторых действий.

2.До недавнего времени пароль по умолчанию поддерживался между сессиями.Но теперь некоторые настройки изменились, и пароль необходимо вводить вручную каждый раз, когда я создаю новый сеанс RDP.

Я подготовил короткий скрипт на python, взаимодействующий с графическим интерфейсом Windows через пакет win32gui.

Я создал автономный исполняемый файл из этого скрипта, используя pyinstaller.И, наконец, я добавил вызов к этому исполняемому файлу прямо в задание.

Примерно так:

while attempts:
    security_window_title = "Windows Security"
    try:
        hwnd_credentials = win32gui.FindWindow(0, security_window_title)

        window_controls = []
        win32gui.EnumChildWindows(hwnd_credentials, collect_window_control, None)

        focus_on_window(hwnd_credentials)
        sleep(0.5)
        prev_user_login = window_controls[2]["hwnd"]

        x = int(window_controls[1]["x"] + 80)
        y = int(window_controls[1]["y"] + 20)

        click(x, y)
        type_message(password)

        ok_button = window_controls[6]["hwnd"]
        push_button(ok_button)

    except win32gui.error:
        sleep(1)
        attempts -= 1
        if not attempts:
            raise RuntimeError("Can't interact with window: {}.".format(security_window_title))
    else:
        break

while attempts:
    sleep(timeout)
    attempts -= 1
    if check_connection_started():
        break

    if check_certificate_errors():
        for control in window_controls[::-1]:
            if control["text"] == "&Yes":
                push_button(control["hwnd"])

    if not attempts:
        raise RuntimeError("Connection not established.")

3.Это не будет проблемой, если скрипт запускается из работы с полнофункциональным интерфейсом Windows.Я могу найти окно, в котором мой скрипт должен указывать пароль, используя пакет python win32gui.Я могу сгенерировать все соответствующие события клавиатуры для ввода пароля.

Использование RDP через консоль предоставляет мне очень странный набор оконоподобных объектов, с которыми я не могу взаимодействовать при использовании пакета python win32gui так же, как и собычные окна.Например, я нахожу окно с ненулевым hwnd и со свойством text, равным «Remote Desktop Connection».Но я не могу сосредоточиться на таком окне, используя базовый метод win32gui.SetForegroundWindow (hwnd).Это приводит к безымянному исключению win32gui.

Есть ли возможность передать пароль нужному элементу управления желаемой оконной структуры, чтобы задание не прерывало его выполнение?

Большое спасибо за любую помощь.

1 Ответ

0 голосов
/ 14 мая 2019

Я могу сосредоточиться как на «подключении к удаленному рабочему столу», так и на «безопасности Windows» с помощью win32gui.SetForegroundWindow(hwnd). Пример кода:

import win32api
import win32gui
import win32con
import time
from pynput.keyboard import Key, Controller

def main():
    Remote = "Remote Desktop Connection"
    Security = "Windows Security"
    try:
        hwnd_Remote = win32gui.FindWindow(0, Remote)
        print(hwnd_Remote)
        win32gui.ShowWindow(hwnd_Remote,win32con.SW_SHOWNORMAL)
        win32gui.SetForegroundWindow(hwnd_Remote)
        keyboard = Controller()
        keyboard.type('ipaddress')
        keyboard.press(Key.enter)
        keyboard.release(Key.enter)
        time.sleep(3)
        hwnd_Security = win32gui.FindWindow(0, Security)
        print(hwnd_Security)
        win32gui.ShowWindow(hwnd_Security,win32con.SW_SHOWNORMAL)
        win32gui.SetForegroundWindow(hwnd_Security)
        keyboard.type('password')
        keyboard.press(Key.enter)
        keyboard.release(Key.enter)
    except win32gui.error:
        raise RuntimeError("Can't interact with window: {}.".format(Remote))

if __name__ == "__main__":
    main()

Убедитесь, что процесс переднего плана не отключил вызовы функции SetForegroundWindow. Добавьте LockSetForegroundWindow(LSFW_UNLOCK) или AllowSetForegroundWindow(ASFW_ANY), чтобы включить вызов SetForegroundWindow.

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