Подача ввода в приложение интерактивной командной строки
Я хотел бы подавать входные данные в интерфейс командной строки для Cisco AnyConnect vpncli.exe
(v2.3) для автоматизации его (повторного) соединения. Он не принимает имя пользователя и пароль как аргументы командной строки, но читает их в интерактивном режиме от пользователя через интерфейс командной строки.
Проблема заключается в том, что вход для подключения к vpncli.exe
не работает для пароля. Он работает для всего, кроме пароля. Так что делать такие вещи не получается:
vpncli.exe < input.txt
type input.txt | vpncli.exe
Приложение просто застревает там, где оно запрашивает пароль.
Ниже приведен пример нормального (рабочего) выполнения, когда пользователь вводит параметры:
![Example vpncli.exe run]()
Обратите внимание, как символы пароля преобразуются в *
.
Использование таких инструментов, как AutoIt или AutoHotKey для отправки входов в окно командной строки, работает, но неудобно и хрупко (не работает, если инструмент по какой-то причине не может попасть в окно командной строки).
Есть ли способ отправить данные для такого интерактивного приложения CLI с помощью PowerShell?
(Или используя любой другой язык сценариев или какие-то другие средства?)
Ответы
Ответ 1
Существует как минимум два способа чтения ввода в консольном приложении Windows.
-
ReadConsole
: считывает ввод с клавиатуры или перенаправления (документация).
-
ReadConsoleInput
: читаются только сырые нажатия клавиш (документация).
Приложение vpncli.exe
использует ReadConsoleInput
, чтобы прочитать пароль, поэтому перенаправление пароля не работает. Вы можете использовать WriteConsoleInput
. У меня есть небольшой Python script, который делает именно это:
import subprocess
import win32console
ANYCONNECT_BIN = 'c:\\Program Files\\Cisco\\Cisco AnyConnect Secure Mobility Client\\vpncli.exe'
def write_console_input(text):
stdin = win32console.GetStdHandle(win32console.STD_INPUT_HANDLE)
ir = win32console.PyINPUT_RECORDType(win32console.KEY_EVENT)
ir.KeyDown = True
for ch in text:
ir.Char = unicode(ch)
stdin.WriteConsoleInput([ir])
def main():
proc = subprocess.Popen([ANYCONNECT_BIN,'connect','VPN'],stdin=subprocess.PIPE)
proc.stdin.write('%s\n%s\n' % ('GROUP', 'USERNAME'))
write_console_input('%s\n' % 'PASSWORD')
ret = proc.wait()
print ret
if __name__ == '__main__':
main()
Ответ 2
вам нужно создать обычный текстовый файл, например
connect myvpnhost
myloginname
мойпароль
сохраните его как myfile.dat(например), а затем вызовите
"% ProgramFiles%\Cisco\Cisco AnyConnect Secure Mobility Client\vpncli.exe" -s < myfile.dat