将输入提供给交互式命令行应用程序

时间:2012-07-14 00:47:22

标签: winapi shell powershell scripting automation

我想将输入馈送到Cisco AnyConnect vpncli.exe(v2.3)的命令行界面,以自动化(重新)连接。它不使用用户名或密码作为命令行参数,而是通过命令行界面从用户以交互方式读取它们。

问题是vpncli.exe的管道输入似乎不适用于密码。它适用于除密码之外的所有内容。所以做这样的事情是行不通的:

vpncli.exe < input.txt
type input.txt | vpncli.exe

应用程序只是卡在要求输入密码的位置。


下面是用户输入参数的正常(工作)执行示例:

Example vpncli.exe run

注意密码字符如何转换为*


使用AutoIt或AutoHotKey等工具将输入发送到命令提示符窗口可以正常工作,但是笨拙而且很脆弱(如果工具由于某种原因无法进入命令提示符窗口,则无效)。


有没有办法使用PowerShell向这样的交互式CLI应用程序发送输入?

(或使用任何其他脚本语言或其他方式?)

2 个答案:

答案 0 :(得分:9)

您需要创建一个通常的文本文件,如

连接myvpnhost
myloginname
输入mypassword

将其保存为myfile.dat(例如),然后调用

&#34;%ProgramFiles%\ Cisco \ Cisco AnyConnect安全移动客户端\ vpncli.exe&#34; -s&lt; MYFILE.DAT

答案 1 :(得分:8)

至少有两种方法可以在Windows控制台应用程序中读取输入。

  • ReadConsole:从键盘或重定向(documentation)读取输入。
  • ReadConsoleInput:只读取原始击键(documentation)。

vpncli.exe应用程序使用ReadConsoleInput来读取密码,重定向密码的方式不起作用。但是,您可以使用WriteConsoleInput。我有一个小的Python脚本,它完全可以做到:

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()