Простой инструмент тестирования программного обеспечения - VB.NET - PullRequest
1 голос
/ 12 апреля 2011

хорошо, пожалуйста, не смейтесь над этим: x
я пытаюсь создать простой инструмент для тестирования программного обеспечения в VB.NET
Я создал простую C-программу PROG.EXE, которая сканирует число и печатает вывод, и начал сборку моего тестера. Он должен выполнить PROG.EXE output.txt , поэтому PROG.EXE принимает данные от input.txt и печатает вывод в output.txt
но мне не удалось, сначала я попробовал Process.start, а затем оболочку, но ничего не получилось!
так что я сделал этот трюк, коды 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  

А это мой код C

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

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

моя программа работает отлично, когда я запускаю prog.exe output.txt в консоли

Ответы [ 2 ]

6 голосов
/ 12 апреля 2011

Ниже приведен полностью рабочий пример.Вы хотите использовать класс 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

РЕДАКТИРОВАТЬ

Вот обновленная версия, которая читает из обоих StandardOutput и StandardError.На этот раз он читает асинхронно.Код вызывает 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, но вы не хотите этого делать.Второй способ - использовать интерпретатор команд 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

EDIT 3

Весь аргумент команды, который вы передаете cmd /C, должен быть заключен в наборцитат.Поэтому, если вы согласитесь, это будет:

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

Вот как должна выглядеть действительная команда, которую вы передаете:

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

Вот полный блок кода.Я добавил обратно средства чтения ошибок и вывод на всякий случай, если вы получаете ошибку разрешения или что-то в этом роде.Так что посмотрите на Immediate Window, чтобы увидеть, исключены ли какие-либо ошибки.Если это не сработает, я не знаю, что вам сказать.

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 голос
/ 30 июля 2012
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...