Vb.net 从cmd命令中提取字符串?StartInfo进程

Vb.net 从cmd命令中提取字符串?StartInfo进程,vb.net,cmd,Vb.net,Cmd,所以我试着处理并启动cmd.exe,然后直接向该窗口发送命令。然后拾取写入cmd.exe窗口的值 代码如下所示: Dim arrServers As ArrayList Dim s(ListBoxServers.Items.Count) As String ListBoxServers.Items.CopyTo(s, 0) arrServers = New ArrayList(s) Using P As New Process P.StartI

所以我试着处理并启动cmd.exe,然后直接向该窗口发送命令。然后拾取写入cmd.exe窗口的值

代码如下所示:

Dim arrServers As ArrayList
    Dim s(ListBoxServers.Items.Count) As String

    ListBoxServers.Items.CopyTo(s, 0)
    arrServers = New ArrayList(s)

    Using P As New Process
        P.StartInfo.FileName = "cmd.exe"
        P.StartInfo.UseShellExecute = False
        P.StartInfo.RedirectStandardOutput = True
        P.StartInfo.RedirectStandardInput = True
        P.Start()
        For Each i In arrServers
            P.StandardInput.WriteLine("query user " & txtBoxUsername.Text & " /server:" & i)
        Next
        P.StandardInput.WriteLine("exit")
        Output = P.StandardOutput.ReadToEnd()
        Trace.WriteLine(Output)
        MsgBox(Output)
        P.WaitForExit()

    End Using
但它看起来并没有“按回车”之类的。也就是说,我没有从命令中得到任何结果。我甚至没有得到一个“'command'不被识别为内部或外部命令、可操作程序或批处理文件”,就像你通常得到的那样,如果它不理解语法

查看System.Diagnostics命名空间中的类以运行批处理文件。

使用类似的库/类进行灵活的参数处理。如果不想使用外部组件,则必须对参数进行循环并手动处理:

For Each arg As String In Environment.GetCommandLineArgs()
  Select Case arg
    Case "/blah"
      ' process /blah '
    Case "/foo"
      ' process foo '
    Case Else
      MsgBox "Unknown argument " + arg " found, aborting.", vbCritical
      Environment.Exit(1)
  End Select
Next

[我通常不做VB,所以这只是一个未经测试的草图]

想象一下下面这个名为“hello.bat”的非常简单的批处理文件

您可以通过以下方式调用它并查看“Hello”:

    'Will hold the results of the batch
    Dim Output As String
    'Create a new process object
    Using P As New Process()
        'Set the script to run
        P.StartInfo.FileName = "c:\scripts\hello.bat"
        'My script doesn't take argument but this is where you would pass them
        P.StartInfo.Arguments = ""
        'Required to redirect output, don't both worrying what it means
        P.StartInfo.UseShellExecute = False
        'Tell the system that you want to see the output
        P.StartInfo.RedirectStandardOutput = True
        'Start your batch
        P.Start()
        'Read the entire contents of the outout
        Output = P.StandardOutput.ReadToEnd()
        'Wait until the batch is done running
        P.WaitForExit()
    End Using
    'Do something with the output
    Trace.WriteLine("Batch produced : " & Output)
编辑

这里有一个版本,它不运行批处理,而是运行两个标准命令。我们首先启动一个命令shell来传递信息。最糟糕的是,运行命令、读取输出然后运行另一个命令很难。下面的代码背靠背运行两个命令,并将整个结果转储到字符串中。如果您需要运行一个命令、处理、运行另一个命令,我认为您必须连接到StandardError并查看返回代码。在你们这样做之前,确保你们已经阅读了关于阻塞的问题,以及其他地方是如何通过连接这样的线程来解决这个问题的。可能更简单的方法是将其包装成一个子集,并为每个命令调用该子集一次

    'Will hold all of the text
    Dim Output As String
    'Create a new process object
    Using P As New Process()
        'Set the script to run the standard command shell
        P.StartInfo.FileName = "cmd.exe"
        'Required to redirect output, don't both worrying what it means
        P.StartInfo.UseShellExecute = False
        'Tell the system that you want to read/write to it
        P.StartInfo.RedirectStandardOutput = True
        P.StartInfo.RedirectStandardInput = True
        'Start your batch
        P.Start()
        'Send your various commands
        P.StandardInput.WriteLine("dir c:\")
        P.StandardInput.WriteLine("ipconfig /all")
        'Very important, send the "exit" command otherwise STDOUT will never close the stream
        P.StandardInput.WriteLine("exit")
        'Read the entire stream
        Output = P.StandardOutput.ReadToEnd()
        'Wait until the batch is done running
        P.WaitForExit()
    End Using
    'Do something with the output
    Trace.WriteLine(Output)
编辑2

一般来说,我在使用“queryuser”命令时遇到了问题,我无法让它为包含空格的用户名返回任何内容,即使我将用户名括在引号中。但这里有一个版本使用了“quser”,据我所知,它做了完全相同的事情

    'Will hold all of the text
    Dim Output As String
    'Create a new process object
    Using P As New Process()
        'Set the script to run the standard command shell
        P.StartInfo.FileName = "cmd.exe"
        'Required to redirect output, don't both worrying what it means
        P.StartInfo.UseShellExecute = False
        'Tell the system that you want to read/write to it
        P.StartInfo.RedirectStandardOutput = True
        P.StartInfo.RedirectStandardInput = True
        'Start your batch
        P.Start()
        'Send your various commands
        'Array of servers
        Dim arrServers() As String = New String() {"SERVER1", "SERVER2"}
        'Loop through array, wrap names with quotes in case they have spaces
        For Each S In arrServers
            P.StandardInput.WriteLine(String.Format("quser ""{0}"" /SERVER:{1}", Me.txtBoxUsername.Text, S))
        Next
        'Very important, send the "exit" command otherwise STDOUT will never close the stream
        P.StandardInput.WriteLine("exit")
        'Read the entire stream
        Output = P.StandardOutput.ReadToEnd()
        'Wait until the batch is done running
        P.WaitForExit()
    End Using
    'Do something with the output
    Trace.WriteLine(Output)

一定要提到ProcessStartInfo.RedirectStandardOutput以使您的答案完整。顺便说一句,我更新了操作代码。但它似乎真的不起作用。我的意思是,我可以写“ipconfig”并在一个字符串框中显示结果。那很好。但不知何故,“queryuser”命令并没有真正给出输出。我所能看到的只是发送到cmd窗口的命令。嗯,同样的事情也会发生。奇怪的是,如果我发送一个看起来像“哈哈哈”之类的输入命令,我会得到同样的结果。换句话说,没有结果。我希望得到“语法错误”之类的东西。就像我手动启动cmd.exe并键入“hahaha”一样,如果您完全按照上面的方式运行代码,它会工作吗?我使用的是Trace.WriteLine,上面的Trace.WriteLine将写入任何配置为跟踪输出的内容,在IDE中,跟踪输出是即时窗口,您确定没有任何内容吗?也许MsgBox会显示结果?不知道还有什么要告诉你的。是的,我确实使用MsgBox来输出结果。但这就像命令本身不提供任何输出一样。这是直接输出的图像。如果我在cmd窗口中手动键入完全相同的字符串,我显然会从中得到一个结果。也许可以尝试调用ECHO ON作为第一个命令,我想不出任何其他原因会导致这种情况
    'Will hold all of the text
    Dim Output As String
    'Create a new process object
    Using P As New Process()
        'Set the script to run the standard command shell
        P.StartInfo.FileName = "cmd.exe"
        'Required to redirect output, don't both worrying what it means
        P.StartInfo.UseShellExecute = False
        'Tell the system that you want to read/write to it
        P.StartInfo.RedirectStandardOutput = True
        P.StartInfo.RedirectStandardInput = True
        'Start your batch
        P.Start()
        'Send your various commands
        'Array of servers
        Dim arrServers() As String = New String() {"SERVER1", "SERVER2"}
        'Loop through array, wrap names with quotes in case they have spaces
        For Each S In arrServers
            P.StandardInput.WriteLine(String.Format("quser ""{0}"" /SERVER:{1}", Me.txtBoxUsername.Text, S))
        Next
        'Very important, send the "exit" command otherwise STDOUT will never close the stream
        P.StandardInput.WriteLine("exit")
        'Read the entire stream
        Output = P.StandardOutput.ReadToEnd()
        'Wait until the batch is done running
        P.WaitForExit()
    End Using
    'Do something with the output
    Trace.WriteLine(Output)