简单的软件测试工具 - VB.NET

Sou*_*rav 1 vb.net

好吧,请不要笑这个:x
我想在VB.NET中创建一个简单的软件测试工具
我创建了一个简单的C程序PROG.EXE,它扫描一个数字并输出OUTPUT,并开始构建我的测试器,它应该执行PROG.EXE output.txt,所以PROG.EXE从input.txt获取输入并将输出打印到output.txt
但我失败了,起初我尝试了Process.start然后shell但没有任何效果!
所以我做了这个技巧,VB.NET代码使用这个代码生成一个批处理文件PROG.EXE output.txt,但我再次失败,虽然VB.NET创建了批处理文件并执行,但没有任何反应!但是当我手动运行批处理文件时,我获得了成功!
我尝试执行批处理文件然后sendkey VBCR/LF/CRLF仍然没有任何反应!
怎么了 ?


我的VB.NET代码,我使用的是Visual Studio 2010 Professional

Option Explicit On  
Option Strict On  
Public Class Form1  
 Dim strFileName As String

 Private Sub btnRun_Click() Handles btnRun.Click  
  Dim strOutput As String  
  Using P As New Process()  
   P.StartInfo.FileName = strFileName  
   P.StartInfo.Arguments = txtInput.Text  
   P.StartInfo.RedirectStandardOutput = True  
   P.StartInfo.UseShellExecute = False  
  P.StartInfo.WindowStyle = ProcessWindowStyle.Hidden  ' will this hide the console ?
   P.Start()  
   Using SR = P.StandardOutput  
    strOutput = SR.ReadToEnd()  
   End Using  
  End Using  
  txtOutput.Text = strOutput  
 End Sub

 Private Sub btnTarget_Click() Handles btnTarget.Click  
  dlgFile.ShowDialog()  
  strFileName = dlgFile.FileName  
  lblFileName.Text = strFileName  
 End Sub  
End Class  
Run Code Online (Sandbox Code Playgroud)

这是我的C代码

#include<stdio.h>  
#include<conio.h>

void main()
{
 int x;
 scanf("%d",&x);
 printf("%d",(x*x));
}
Run Code Online (Sandbox Code Playgroud)

当我在控制台中运行prog.exe <input.txt> output.txt时,我的程序运行完美

Chr*_*aas 6

下面是一个完整的例子.您希望在Process尝试时使用该类,但您需要RedirectStandardOutput使用该过程StartInfo.然后你就可以阅读这个过程了StandardOutput.下面的示例是使用VB 2010编写的,但对于旧版本的工作方式几乎相同.

Option Explicit On
Option Strict On

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ''//This will hold the entire output of the command that we are running
        Dim T As String

        ''//Create our process object
        Using P As New Process()
            ''//Pass it the EXE that we want to execute
            ''//NOTE: you might have to use an absolute path here
            P.StartInfo.FileName = "ping.exe"

            ''//Pass it any arguments needed
            ''//NOTE: if you pass a file name as an argument you might have to use an absolute path
            P.StartInfo.Arguments = "127.0.0.1"

            ''//Tell the process that we want to handle the commands output stream
            ''//NOTE: Some programs also write to StandardError so you might want to watch that, too
            P.StartInfo.RedirectStandardOutput = True

            ''//This is needed for the previous line to work
            P.StartInfo.UseShellExecute = False

            ''//Start the process
            P.Start()

            ''//Wrap a StreamReader around the standard output
            Using SR = P.StandardOutput
                ''//Read everything from the stream
                T = SR.ReadToEnd()
            End Using
        End Using

        ''//At this point T will hold whatever the process with the given arguments kicked out
        ''//Here we are just dumping it to the screen
        MessageBox.Show(T)
    End Sub
End Class
Run Code Online (Sandbox Code Playgroud)

编辑

这是一个更新版本,可以读取StandardOutputStandardError.这次它是异步读取的.代码调用CHOICEexe并传递一个无效的命令行开关,它将触发写入StandardError而不是StandardOutput.对于您的程序,您应该监视两者.此外,如果要将文件传递给程序,请确保指定文件的绝对路径,并确保如果文件路径中包含用引号括起路径的空格.

Option Explicit On
Option Strict On

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ''//This will hold the entire output of the command that we are running
        Dim T As String

        ''//Create our process object
        Using P As New Process()
            ''//Pass it the EXE that we want to execute
            ''//NOTE: you might have to use an absolute path here
            P.StartInfo.FileName = "choice"

            ''//Pass it any arguments needed
            ''//NOTE: if you pass a file name as an argument you might have to use an absolute path
            ''//NOTE: I am passing an invalid parameter to show off standard error
            P.StartInfo.Arguments = "/G"

            ''//Tell the process that we want to handle the command output AND error streams
            P.StartInfo.RedirectStandardOutput = True
            P.StartInfo.RedirectStandardError = True

            ''//This is needed for the previous line to work
            P.StartInfo.UseShellExecute = False

            ''//Add handlers for both of the data received events
            AddHandler P.ErrorDataReceived, AddressOf ErrorDataReceived
            AddHandler P.OutputDataReceived, AddressOf OutputDataReceived

            ''//Start the process
            P.Start()

            ''//Start reading from both error and output
            P.BeginErrorReadLine()
            P.BeginOutputReadLine()

            ''//Signal that we want to pause until the program is done running
            P.WaitForExit()


            Me.Close()
        End Using
    End Sub

    Private Sub ErrorDataReceived(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
        Trace.WriteLine(String.Format("From Error  : {0}", e.Data))
    End Sub
    Private Sub OutputDataReceived(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
        Trace.WriteLine(String.Format("From Output : {0}", e.Data))
    End Sub
End Class
Run Code Online (Sandbox Code Playgroud)

重要的是你把整个文件路径放在引号中如果它有空格(实际上,你应该总是将它括在引号中以防万一.)例如,这不起作用:

P.StartInfo.FileName = "attrib"
P.StartInfo.Arguments = "C:\Program Files\Windows NT\Accessories\wordpad.exe"
Run Code Online (Sandbox Code Playgroud)

但这会:

P.StartInfo.FileName = "attrib"
P.StartInfo.Arguments = """C:\Program Files\Windows NT\Accessories\wordpad.exe"""
Run Code Online (Sandbox Code Playgroud)

编辑2

好吧,我是个白痴.我以为你只是将文件名包装在斜角括号中,<input.txt>或者[input.txt],我没有意识到你使用的是实际的流重定向器!(之前和之后的空间input.txt会有所帮助.)对于困惑感到抱歉.

有两种方法可以处理与Process对象的流重定向.第一种是手动读取input.txt和写入StandardInput,然后读取StandardOutput和写入,output.txt但您不想这样做.第二种方法是使用Windows命令解释器,cmd.exe它具有一个特殊参数/C.传递后,它会为你执行任何字符串.所有流重定向都像在命令行中键入它们一样工作.重要的是,无论您传递的任何命令都包含在引号中,因此除了文件路径之外,您还会看到一些双引号.所以这是一个完成所有这些的版本:

Option Explicit On
Option Strict On

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ''//Full path to our various files
        Dim FullExePath As String = "C:\PROG.exe"
        Dim FullInputPath As String = "C:\input.txt"
        Dim FullOutputPath As String = "C:\output.txt"

        ''//This creates our command using quote-escaped paths, all completely wrapped in an extra set of quotes
        ''//""C:\PROG.exe" < "C:\input.txt" > "C:\output.txt""
        Dim FullCommand = String.Format("""""{0}"" < ""{1}"" > ""{2}""""", FullExePath, FullInputPath, FullOutputPath)
        ''//Create our process object
        Using P As New Process()
            ''//We are going to use the command shell and tell it to process our command for us
            P.StartInfo.FileName = "cmd"

            ''//The /C (capitalized) means "execute whatever else is passed"
            P.StartInfo.Arguments = "/C " & FullCommand

            ''//Start the process
            P.Start()

            ''//Signal to wait until the process is done running
            P.WaitForExit()
        End Using

        Me.Close()
    End Sub
End Class
Run Code Online (Sandbox Code Playgroud)

编辑3

传递给的整个命令参数cmd /C需要包含在一组引号中.所以如果你连续它会是:

Dim FullCommand as String = """""" & FullExePath & """" & " <""" & FullInputPath & """> " & """" & FullOutputPath & """"""
Run Code Online (Sandbox Code Playgroud)

以下是您传递的实际命令应如下所示:

cmd /C ""C:\PROG.exe" < "C:\INPUT.txt" > "C:\output.txt""
Run Code Online (Sandbox Code Playgroud)

这是一个完整的代码块.我已经添加了错误并输出了读者,以防您收到权限错误或其他内容.因此,请查看立即窗口以查看是否有任何错误被踢出.如果这不起作用,我不知道该告诉你什么.

Option Explicit On
Option Strict On

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ''//Full path to our various files
        Dim FullExePath As String = "C:\PROG.exe"
        Dim FullInputPath As String = "C:\INPUT.txt"
        Dim FullOutputPath As String = "C:\output.txt"

        ''//This creates our command using quote-escaped paths, all completely wrapped in an extra set of quotes
        Dim FullCommand As String = """""" & FullExePath & """" & " <""" & FullInputPath & """> " & """" & FullOutputPath & """"""
        Trace.WriteLine("cmd /C " & FullCommand)


        ''//Create our process object
        Using P As New Process()
            ''//We are going to use the command shell and tell it to process our command for us
            P.StartInfo.FileName = "cmd"

            ''//Tell the process that we want to handle the command output AND error streams
            P.StartInfo.RedirectStandardError = True
            P.StartInfo.RedirectStandardOutput = True

            ''//This is needed for the previous line to work
            P.StartInfo.UseShellExecute = False

            ''//Add handlers for both of the data received events
            AddHandler P.ErrorDataReceived, AddressOf ErrorDataReceived
            AddHandler P.OutputDataReceived, AddressOf OutputDataReceived

            ''//The /C (capitalized) means "execute whatever else is passed"
            P.StartInfo.Arguments = "/C " & FullCommand

            ''//Start the process
            P.Start()


            ''//Start reading from both error and output
            P.BeginErrorReadLine()
            P.BeginOutputReadLine()


            ''//Signal to wait until the process is done running
            P.WaitForExit()
        End Using

        Me.Close()
    End Sub
    Private Sub ErrorDataReceived(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
        Trace.WriteLine(String.Format("From Error  : {0}", e.Data))
    End Sub
    Private Sub OutputDataReceived(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
        Trace.WriteLine(String.Format("From Output : {0}", e.Data))
    End Sub
End Class
Run Code Online (Sandbox Code Playgroud)