我需要自动化命令行应用程序。它要求用户输入密码。我通过 STDIN 发送密码的所有方法都失败了。现在我正在尝试使用.NET 的包装程序来做到这一点。
我正在启动应用程序,创建一个新进程,设置StartInfo
-properties,然后启动该进程:
Dim app_path As String
Dim app_args As String
Dim myProcess As Process = New Process()
myProcess.StartInfo.FileName = app_path
myProcess.StartInfo.Arguments = app_args
myProcess.StartInfo.UseShellExecute = False
myProcess.Start()
我确实尝试使用该StartInfo.RedirectStandardInput
属性,但没有成功。
现在我遇到了我包含的WriteConsoleInput
函数,如下所示:kernel32.dll
Declare Function WriteConsoleInput Lib "kernel32.dll" Alias "WriteConsoleInputA" (ByVal hConsoleInput As Integer, ByVal lpBuffer As String, ByVal nNumberOfCharsToWrite As Integer, ByRef lpNumberOfCharsWritten As Integer) As Boolean
myProcess.Handle
我可以通过属性获取进程的句柄。但是使用这种方式将输入发送到输入缓冲区也是不可能的。
我发现了这些问题,但它们没有帮助:
如何将“PAGE DOWN”写入控制台输入缓冲区?(1475353)
Java - 将输入传递到外部 C/C++ 应用程序 (1421273)
使用标准输入管道控制 Windows 控制台应用程序 (723424)
使用 StraceNtX.exe 我在应用程序等待输入的那一刻得到了这个输出:
[T4024] GetConsoleMode(f, 12d35c, 12d3af, 77bff894, ...) = 1
[T4024] SetConsoleMode(f, 0, 12d3af, 77bff894, ...) = 1
[T4024] ReadConsoleInputA(f, 12d348, 1, 12d360, ...) = 1
谁能告诉我,还有什么可以尝试或如何以正确的方式进行上述操作?谢谢!
根据 Tim Robinsons 的回答,我现在得到了这段代码,但它不起作用:
myProcess = New Process()
myProcess.StartInfo.FileName = app_path
myProcess.StartInfo.Arguments = app_args
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal
myProcess.StartInfo.UseShellExecute = False
myProcess.Start()
' Wait for process requesting passwort input
System.Threading.Thread.Sleep(3000)
Dim len As Integer
len = 0
Dim handle As Integer
handle = GetStdHandle(STD_INPUT_HANDLE)
WriteConsoleInput(handle, "Test", 4, len)
我的程序是一个命令行应用程序,应该充当包装器。
输入是发送的,但不是在密码字段中输入,而是在密码字段下方显示一个新的提示(甚至不显示输入)。
蒂姆,你能给我举个例子吗?