【问题标题】:User input on command prompt命令提示符下的用户输入
【发布时间】:2023-03-25 06:23:01
【问题描述】:

我需要在 VB.net 中自动使用命令行实用程序。这是一个例子。

从代码中,我需要使用命令行实用程序解密文件。这是命令行过程。

您使用此行启动实用程序

C:\gnupg>gpg --decrypt c:\temp\File_Encr.xml

一旦执行,就会显示这个

You need a passphrase to unlock the secret key for user: "xxxx <abc@def.com>" 1024-bit ELG-E key, ID ABCD, created 2013-10-25 (main key ID DEF)

输入密码:

当您输入密码时,它就可以完成工作。 我需要从代码(VB.NET)开始这个过程并输入密码,这样它就不需要任何用户交互。我的代码将用于 Windows 服务以及 Web 应用程序。

有人可以帮忙吗?

谢谢。 萨默斯

【问题讨论】:

  • 给定程序必须允许您将“用户输入”作为参数引入;您必须遵循给定问题的规则/语法。您所指程序的相关页面:spywarewarrior.com/uiuc/gpg/gpg-com-4.htm
  • 我明白,如果是这样的话,我不需要花这么多时间在这件事上。问题是,当我们调用它时,程序似乎不支持通过命令行输入密码。它只在执行主命令行时询问。
  • 如前所述,如果目标程序不允许您通过命令提示符与其交互,则无法进行。在最有可能的情况下,它允许您但您没有明确的确切语法。解决此问题的唯一方法(如果可能的话)是查看目标软件制造商提供的说明;除了(盲目的)试错之外,您无能为力(通过 Process 类)。

标签: vb.net command-line command-line-arguments command-prompt


【解决方案1】:

这是我使用的代码 sn-p。

为方便起见,所有输出代码都写入 Visual Studio 调试窗口。所有程序输出都重定向到输出处理程序。这使您可以“实时”检查程序的输出。如果您需要查看输出行并扫描某个短语然后执行操作,您可以在 Sub OutputReceivedHandler() 中轻松完成。

我试图让它通用,以便你可以看到它是如何工作的:

Imports Microsoft.VisualBasic Imports System.Diagnostics Imports System Public Class ExternalUtilities Private myprocess As Process Private SW As System.IO.StreamWriter Private myprocess_HasError As Boolean = False Private myprocess_ErrorMsg As String = "" Private myprocess_Output As String = "" Public Sub New() ' do init stuff here. ' maybe pass the executable path, or command line args. End Sub Public Sub launchUtilityProcess1() Dim executeableFullPath As String = "C:\Path\To\file.exe" ' define the process myprocess = New Process myprocess.StartInfo.FileName = executeableFullPath myprocess.StartInfo.RedirectStandardInput = True myprocess.StartInfo.RedirectStandardOutput = True myprocess.StartInfo.RedirectStandardError = True myprocess.StartInfo.UseShellExecute = False myprocess.StartInfo.CreateNoWindow = True myprocess.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(executeableFullPath) myprocess.StartInfo.Arguments = "--decrypt c:\temp\File_Encr.xml" ' add handlers to monitor various conditions myprocess.EnableRaisingEvents = True AddHandler myprocess.OutputDataReceived, AddressOf OutputReceivedHandler AddHandler myprocess.ErrorDataReceived, AddressOf ErrorReceivedHandler AddHandler myprocess.Exited, AddressOf ExitedHandler ' launch Try myprocess.Start() ' redirect this processes IO SW = myprocess.StandardInput SW.AutoFlush = True ' use asynchronous reading so buffers dont fill up myprocess.BeginOutputReadLine() myprocess.BeginErrorReadLine() ' wait for program to end myprocess.WaitForExit() myprocess.Close() SW.Close() myprocess.Dispose() ' check for errors If myprocess_ErrorMsg "" Then ' something bad happened, handle it. End If Catch ex As Exception ' something bad happened, handle it. End Try End Sub Private Sub OutputReceivedHandler(ByVal sendingProcess As Object, ByVal line As DataReceivedEventArgs) If Not line.Data Is Nothing Then If line.Data = "string to search for..." Then ' when this string is detected, send more output SW.Write("helloworld" & System.Environment.NewLine) ElseIf line.Data = "something else..." Then ' when this string is detected, send more output SW.Write("goodbyeworld" & System.Environment.NewLine) End If Debug.WriteLine(line.Data) End If End Sub Private Sub ErrorReceivedHandler(ByVal sendingProcess As Object, ByVal line As DataReceivedEventArgs) Debug.WriteLine(line.Data) ' These executables send newlines on the STDERR path, ignore newlines If line.Data <> "" Then myprocess_HasError = True myprocess_ErrorMsg = line.Data End If End Sub Private Sub ExitedHandler(ByVal sender As Object, ByVal e As System.EventArgs) Debug.WriteLine("Process Exited") End Sub End Class

【讨论】:

  • 我试过这个并且执行永远不会超出 myprocess.WaitForExit() 语句。任何想法?谢谢
  • 在 Visual Studio 中检查您的调试窗口,该程序可能正在等待更多用户输入。您可以检查 Sub OutputReceivedHandler() 中的行并根据打印的行做出决定。如果需要,您可以将“myprocess”移动到更广泛的范围内,以便子例程可以访问它并发送更多命令。
  • 我已经试过了,那里什么都没有。甚至为 OutputReceivedHandler 和 ErrorReceivedHandler 和 ExitedHandler 添加了断点,但它永远不会到达那里。 (突然卡在 myprocess.WaitForExit() 上。如果我在命令提示符上手动输入密码(我尝试让它可见),那么它会继续下去。否则,它就会卡在那里。
  • 我使用这个确切的代码来运行各种命令行可执行文件。当然,它需要一些定制。我不确定你的程序是如何工作的。例如,如果您需要在进程执行时直接传递参数,请尝试:myprocess.StartInfo.Arguments = "--decrypt c:\temp\File_Encr.xml"
  • 大卫,非常感谢您的帮助。对我来说很多。是的,我已经尝试过提供参数(没有它甚至没有正确启动该过程)。我期望的是,当我们使用 SW.Write ("password" & vbCRLF or Envoirnment.NewLine) 或 SW.WriteLine("Password") 应用程序应该转到下一行(在接受密码后)。但是,它仍然停留在那条线上并且不会继续。我会尝试更多的调整,看看是否有效。
最近更新 更多