Simple software testing tool - VB.NET

前端 未结 2 1032
星月不相逢
星月不相逢 2020-12-10 23:43

ok, please do no laugh at this :x
i\'m trying to create a simple software testing tool in VB.NET
i created a simple C program PROG.EXE which scans a number and p

相关标签:
2条回答
  • 2020-12-11 00:03

    Below is a fully working example. You want to use the Process class as you tried but you need to RedirectStandardOutput on the process's StartInfo. Then you can just read the process's StandardOutput. The sample below is written using VB 2010 but works pretty much the same for older versions.

    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
    

    EDIT

    Here is an updated version that reads from both StandardOutput and StandardError. This time it reads asynchronously. The code calls the CHOICE exe and passes an invalid command line switch which will trigger writing to StandardError instead of StandardOutput. For your program you should probably monitor both. Also, if you're passing a file into the program make sure that you are specifying the absolute path to the file and make sure that if you have spaces in the file path that you are wrapping the path in quotes.

    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
    

    Its important that you put your entire file path in quotes if it has spaces in it (in fact, you should always enclose it in quotes just in case.) For instance, this won't work:

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

    But this will:

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

    EDIT 2

    Okay, I'm an idiot. I thought you were just wrapping a filename in angled brackets like <input.txt> or [input.txt], I didn't realize that you were using actual stream redirectors! (A space before and after input.txt would have helped.) Sorry for the confusion.

    There are two ways to handle stream redirection with the Process object. The first is to manually read input.txt and write it to StandardInput and then read StandardOutput and write that to output.txt but you don't want to do that. The second way is to use the Windows command interpreter, cmd.exe which has a special argument /C. When passed it executes any string after it for you. All stream redirections work as if you typed them at the command line. Its important that whatever command you pass gets wrapped in quotes so along with the file paths you'll see some double-quoting. So here's a version that does all that:

    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
    

    EDIT 3

    The entire command argument that you pass to cmd /C needs to be wrapped in a set of quotes. So if you concat it it would be:

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

    Here's what the actual command that you pass should look like:

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

    Here's a full code block. I've added back the error and output readers just in case you're getting a permission error or something. So look at the Immediate Window to see if any errors are kicked out. If this doesn't work I don't know what to tell you.

    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
    
    0 讨论(0)
  • 2020-12-11 00:18
    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
    
    0 讨论(0)
提交回复
热议问题