Winapi 向交互式命令行应用程序提供输入

Winapi 向交互式命令行应用程序提供输入,winapi,shell,powershell,scripting,automation,Winapi,Shell,Powershell,Scripting,Automation,我想为Cisco AnyConnectvpncli.exe(v2.3)的命令行界面提供输入,以自动(重新)连接。它不使用用户名或密码作为命令行参数,而是通过命令行界面从用户处以交互方式读取这些参数 问题是vpncli.exe的管道输入对于密码似乎不起作用。它适用于除密码之外的所有内容。这样做是行不通的: vpncli.exe < input.txt type input.txt | vpncli.exe vpncli.exe

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

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

vpncli.exe < input.txt
type input.txt | vpncli.exe
vpncli.exe
应用程序只是停留在请求密码的地方


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

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


使用诸如AutoIt或AutoHotKey之类的工具将输入发送到命令提示窗口是可行的,但这是笨拙和脆弱的(如果工具由于某种原因无法到达命令提示窗口,则不起作用)


是否有任何方法可以使用PowerShell向此类交互式CLI应用程序发送输入


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

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

  • ReadConsole
    :从键盘或重定向()读取输入
  • ReadConsoleInput
    :仅读取原始击键()
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()

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

连接myvpnhost
myloginname
我的密码

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


%ProgramFiles%\Cisco\Cisco AnyConnect安全移动客户端\vpncli.exe“-s会有帮助-@AngshumanAgarwal,不幸的是,不是,这是一个不同版本的VPN客户端。尝试-尝试将击键发送到控制台窗口。谢谢,很好的信息/ref和示例。尽管我最终使用了带有AHK的
ControlSend
来向控制台窗口发送击键(即使窗口最小化,也可以正常工作,等等)。在问题中,我说这完全不起作用。或者你是说
-s
标志使它工作?该标志的作用是什么?是,-s标志只是使用Cisco AnyConnect安全移动客户端(版本3.0.08057)扩展stdin(如果您不信任我,只需运行vpncli.exe/?:-),
-s
标志不再是一个选项(因此此答案不起作用),是否还有其他解决方法?