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

时间:2011-04-12 12:16:48

标签: 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专业版

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  

这是我的C代码

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

void main()
{
 int x;
 scanf("%d",&x);
 printf("%d",(x*x));
}

当我运行 prog.exe&lt; input.txt&gt;时,我的程序运行正常。控制台中的output.txt

2 个答案:

答案 0 :(得分: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

修改

以下是从StandardOutputStandardError读取的更新版本。这次它是异步读取的。代码调用CHOICE exe并传递无效的命令行开关,该开关将触发写入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

如果文件路径中有空格,那么将整个文件路径放在引号中很重要(事实上,为了以防万一,您应该始终将它括在引号中。)例如,这不起作用:

P.StartInfo.FileName = "attrib"
P.StartInfo.Arguments = "C:\Program Files\Windows NT\Accessories\wordpad.exe"

但这会:

P.StartInfo.FileName = "attrib"
P.StartInfo.Arguments = """C:\Program Files\Windows NT\Accessories\wordpad.exe"""

编辑2

好吧,我是个白痴。我以为你只是用<input.txt>[input.txt]等角括号括起文件名,我没有意识到你使用的是实际的流重定向器! (input.txt之前和之后的空格会有所帮助。)对于这种混乱感到抱歉。

有两种方法可以使用Process对象处理流重定向。第一种是手动阅读input.txt并将其写入StandardInput,然后阅读StandardOutput并将其写入output.txt,但您不想这样做。第二种方法是使用具有特殊参数cmd.exe的Windows命令解释器/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

编辑3

传递给cmd /C的整个命令参数需要包含在一组引号中。所以,如果你结束它将是:

Dim FullCommand as String = """""" & FullExePath & """" & " <""" & FullInputPath & """> " & """" & FullOutputPath & """"""

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

cmd /C ""C:\PROG.exe" < "C:\INPUT.txt" > "C:\output.txt""

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

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

答案 1 :(得分:1)

Public Class attributeclass
  Public index(7) As ctrarray
End Class

Public Class ctrarray
  Public nameclass As String
  Public ctrlindex(10) As ctrlindexclass
End Class

Public Class ctrlindexclass
  Public number As Integer
  Public names(10) As String
  Public status(10) As Boolean

  Sub New()
    number = 0
    For i As Integer = 0 To 10
        names(i) = "N/A"
        status(i) = False
    Next
  End Sub
End Class

Public attr As New attributeclass

Sub Main()
  attr.index(1).nameclass = "adfdsfds"
  System.Console.Write(attr.index(1).nameclass)
  System.Console.Read()
End Sub