User input on command prompt - vb.net

I need to automate usage of a command line utility in VB.net. here is an example.
From the code, I need to decrypt a file using command line utility. Here is the command line procedure.
You start utility using this line
C:\gnupg>gpg --decrypt c:\temp\File_Encr.xml
Once executed, then it shows this
You need a passphrase to unlock the secret key for
user: "xxxx <abc#def.com>"
1024-bit ELG-E key, ID ABCD, created 2013-10-25 (main key ID DEF)
Enter passphrase:
and when you enter the passphrase, it do the job.
I need start this process from the code (VB.NET) and input passphrase as well so that it doesn't require any user interaction. My code will be used in Windows Services as well as Web application.
Can someone help on this please?
Thank you.
Sameers

Here is a code snippet I use.
All output code is written to the Visual Studio debug window for convenience. All program output all redirected to output handlers. This allows you to inspect the output coming out of the program in "real time". If you needed to watch the output lines and scan for a certain phrase and then perform an action, you could easily do this in Sub OutputReceivedHandler().
I tried to make it generic so you can see how it works:
Imports Microsoft.VisualBasic
Imports System.Diagnostics
Imports System
Public Class ExternalUtilities
Private myprocess As Process
Private SW As System.IO.StreamWriter
Private myprocess_HasError As Boolean = False
Private myprocess_ErrorMsg As String = ""
Private myprocess_Output As String = ""
Public Sub New()
' do init stuff here.
' maybe pass the executable path, or command line args.
End Sub
Public Sub launchUtilityProcess1()
Dim executeableFullPath As String = "C:\Path\To\file.exe"
' define the process
myprocess = New Process
myprocess.StartInfo.FileName = executeableFullPath
myprocess.StartInfo.RedirectStandardInput = True
myprocess.StartInfo.RedirectStandardOutput = True
myprocess.StartInfo.RedirectStandardError = True
myprocess.StartInfo.UseShellExecute = False
myprocess.StartInfo.CreateNoWindow = True
myprocess.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(executeableFullPath)
myprocess.StartInfo.Arguments = "--decrypt c:\temp\File_Encr.xml"
' add handlers to monitor various conditions
myprocess.EnableRaisingEvents = True
AddHandler myprocess.OutputDataReceived, AddressOf OutputReceivedHandler
AddHandler myprocess.ErrorDataReceived, AddressOf ErrorReceivedHandler
AddHandler myprocess.Exited, AddressOf ExitedHandler
' launch
Try
myprocess.Start()
' redirect this processes IO
SW = myprocess.StandardInput
SW.AutoFlush = True
' use asynchronous reading so buffers dont fill up
myprocess.BeginOutputReadLine()
myprocess.BeginErrorReadLine()
' wait for program to end
myprocess.WaitForExit()
myprocess.Close()
SW.Close()
myprocess.Dispose()
' check for errors
If myprocess_ErrorMsg "" Then
' something bad happened, handle it.
End If
Catch ex As Exception
' something bad happened, handle it.
End Try
End Sub
Private Sub OutputReceivedHandler(ByVal sendingProcess As Object, ByVal line As DataReceivedEventArgs)
If Not line.Data Is Nothing Then
If line.Data = "string to search for..." Then
' when this string is detected, send more output
SW.Write("helloworld" & System.Environment.NewLine)
ElseIf line.Data = "something else..." Then
' when this string is detected, send more output
SW.Write("goodbyeworld" & System.Environment.NewLine)
End If
Debug.WriteLine(line.Data)
End If
End Sub
Private Sub ErrorReceivedHandler(ByVal sendingProcess As Object, ByVal line As DataReceivedEventArgs)
Debug.WriteLine(line.Data)
' These executables send newlines on the STDERR path, ignore newlines
If line.Data <> "" Then
myprocess_HasError = True
myprocess_ErrorMsg = line.Data
End If
End Sub
Private Sub ExitedHandler(ByVal sender As Object, ByVal e As System.EventArgs)
Debug.WriteLine("Process Exited")
End Sub
End Class

Related

Vb.NET Start Process and return output

I'm trying to execute some command line commands (putty). Now it may be that the command line waits for an input (simplest example: password maybe wrong). All the output should be written into Console.
My code displays a non-ending command line that does not write anything to the console.
Imports System.Text
Public Class Form1
Private Shared processOutput As StringBuilder = Nothing
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim line As String = "/c plink -ssh chef#192.168.178.35 -pw 12345678 -m C:\putty\pw\putty.txt"
processOutput = New StringBuilder()
Dim objP As New System.Diagnostics.Process()
Dim objPi As ProcessStartInfo = New ProcessStartInfo()
With objPi
.FileName = "cmd.exe"
.Arguments = line
.RedirectStandardOutput = True
.RedirectStandardError = True
.RedirectStandardInput = True
.UseShellExecute = False
.WindowStyle = ProcessWindowStyle.Hidden
.CreateNoWindow = False
End With
objP.StartInfo = objPi
AddHandler objP.OutputDataReceived, AddressOf OutputHandler
objP.Start()
objP.BeginOutputReadLine()
objP.WaitForExit(1000)
Debug.WriteLine(processOutput.ToString())
End Sub
Private Shared Sub OutputHandler(sendingProcess As Object, outLine As DataReceivedEventArgs)
If Not String.IsNullOrEmpty(outLine.Data) Then
processOutput.AppendLine(outLine.Data)
End If
End Sub
End Class
As Stephen mentioned, your are not printing anything to the console, only writing to the StringBuilder object. So you have to print the content of StringBuilder object to the console to actually see a result:
Console.WriteLine(processOutput)
MSDN example see:
https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.outputdatareceived?view=netframework-4.7.2
it's because you're not writing anything to console or the UI. Debug.write is not the same as console.write
Additionally, your delegate function may be returning after 1 second. A better paradigm would use await.
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' Call the method that runs asynchronously.
Dim result As String = Await WaitAsynchronouslyAsync()
' Call the method that runs synchronously.
'Dim result As String = Await WaitSynchronously()
' Display the result.
TextBox1.Text &= result
End Sub
' The following method runs asynchronously. The UI thread is not
' blocked during the delay. You can move or resize the Form1 window
' while Task.Delay is running.
Public Async Function WaitAsynchronouslyAsync() As Task(Of String)
Await Task.Delay(10000)
Return "Finished"
End Function
' The following method runs synchronously, despite the use of Async.
' You cannot move or resize the Form1 window while Thread.Sleep
' is running because the UI thread is blocked.
Public Async Function WaitSynchronously() As Task(Of String)
' Import System.Threading for the Sleep method.
Thread.Sleep(10000)
Return "Finished"
End Function
https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/await-operator

Wait until download is complete before starting other tasks

I am trying to download a file, and then run some adb commands. However when downloading, i could not get it to update the progress bar using
downloadFile(url,filename)` command.
A bit of searching it said that the command was blocking the UI thread, so i decided to use Task.Run() (a solution to my previous post to run ADB Commands when it blocked the UIThread).
This made no difference. Another solution that i found is to use
downloadFileAsync(url, filename)
The progress bar is updating!
But, the ADB commands are running before the file is downloaded! They are declared after, but they are still being run before the file is downloaded, which I don't want.
Here is the code:
Private Sub btnFlashRecovery_Click(sender As Object, e As EventArgs) Handles btnFlashRecovery.Click
'Insert ommited Code here (removed to simplify question)
'id is variable obtained from a previous code that was ommited here
Dim fileName As String = "downloads/twrp-" & id & ".img"
DownloadFile(url, fileName)
'run the right commands
LabelToOutput = txtBoxRecovery
Dim commands(3, 3) As String
commands = {{"adb", "reboot bootloader", "Rebooting to bootloader"},
{"fastboot", "flash recovery" & "downloads/twrp-3.1.1-0.img", "Flashing recovery: (make sure device is plugged, otherwise it will not output anything)"},
{"fastboot", "reboot", "Rebooting device"}
}
'Task to run after
Task.Run(Sub() runComands(commands))
End Sub
Private Sub UpdateProgressBar(ByVal a As Integer)
If Me.InvokeRequired Then
Dim args() As String = {a}
Me.Invoke(New Action(Of String)(AddressOf UpdateProgressBar), args)
Return
End If
ProgressBar1.Value = CInt(a)
End Sub
Public Sub DownloadFile(urlAddress As String, location As String)
Using webClient = New WebClient()
AddHandler webClient.DownloadFileCompleted, AddressOf Completed
AddHandler webClient.DownloadProgressChanged, AddressOf ProgressChanged
Try
' Start downloading the file
webClient.DownloadFileAsync(New Uri(urlAddress), location)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Using
End Sub
' The event that will fire whenever the progress of the WebClient is changed
Private Sub ProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs)
'Console.WriteLine(e.ProgressPercentage)
' Update the progressbar percentage only when the value is not the same.
UpdateProgressBar(e.ProgressPercentage)
End Sub
' The event that will trigger when the WebClient is completed
Private Sub Completed(sender As Object, e As AsyncCompletedEventArgs)
If e.Cancelled = True Then
MessageBox.Show("Download has been canceled.")
Else
MessageBox.Show("Download completed!")
End If
End Sub
Do it like this:
'Need Async keyword with the method
Private Async Sub btnFlashRecovery_Click(sender As Object, e As EventArgs) Handles btnFlashRecovery.Click
'Insert ommited Code here (removed to simplify question)
'id is variable obtained from a previous code that was ommited here
Dim fileName As String = "downloads/twrp-" & id & ".img"
'You need to AWAIT the result of the task
Await Task.Run(Sub() DownloadFile(url, fileName))
'run the right commands
LabelToOutput = txtBoxRecovery
Dim commands(3, 3) As String
commands = { {"adb", "reboot bootloader", "Rebooting to bootloader"},
{"fastboot", "flash recovery" & "downloads/twrp-3.1.1-0.img", "Flashing recovery: (make sure device is plugged, otherwise it will not output anything)"},
{"fastboot", "reboot", "Rebooting device"}
}
'Task to run after
'Await here, too, to allow the UI to remain responsive
Await Task.Run(Sub() runComands(commands))
End Sub

Reading Output from cmd asynchronously

I'm using this code:
Shared sb_OutputData As New StringBuilder()
Shared sb_ErrorData As New StringBuilder()
Shared proc As Process = Nothing
Private Sub cmd()
If proc IsNot Nothing Then
Exit Sub
End If
Dim info As New ProcessStartInfo("cmd.exe")
' Redirect the standard output of the process.
info.RedirectStandardOutput = True
info.RedirectStandardInput = True
info.RedirectStandardError = True
' Set UseShellExecute to false for redirection
info.UseShellExecute = False
proc = New Process
proc.StartInfo = info
' Set our event handler to asynchronously read the sort output.
AddHandler proc.OutputDataReceived, AddressOf proc_OutputDataReceived
AddHandler proc.ErrorDataReceived, AddressOf proc_ErrorDataReceived
proc.Start()
' Start the asynchronous read of the sort output stream. Note this line!
proc.BeginOutputReadLine()
proc.BeginErrorReadLine()
End Sub
Private Shared Sub proc_ErrorDataReceived(sender As Object, e As DataReceivedEventArgs)
'Console.WriteLine("Error data: {0}", e.Data)
sb_ErrorData.AppendLine(e.Data)
End Sub
Private Shared Sub proc_OutputDataReceived(sender As Object, e As DataReceivedEventArgs)
' Console.WriteLine("Output data: {0}", e.Data)
sb_OutputData.AppendLine(e.Data)
End Sub
Sub CmdWrite(arguments As String)
Dim writeStream As StreamWriter = proc.StandardInput
writeStream.WriteLine(arguments)
End Sub
It works exactly as I want, be able to retrieve cmd output and error data without closing it (and asynchronously), however, I'm not able to know when the command is finished executing. I'd like to know when it reaches the end of the stream for me to grab all the output and do something with it...
I've been searching for quite long, and can't find an answer to this.
Help please?
The stream is open is long as the command window is open. You can't tell when they stop or start. If the command you're running doesn't indicate its end with a unique/detectable pattern, you're stuck, unless you can edit the script you're running and insert a string - which you can't guarantee won't show in the normal output - in between the command calls.

Console application doesn't want to read standard input

I am writing an application to manage other console application(game server - jampded.exe)
When it's running in console it writes data and reads commands with no problem.
In my application I redirected standard I/O to StreamWriter and StreamReader
Public out As StreamReader
Public input As StreamWriter
Dim p As New Process()
p.StartInfo.FileName = My.Application.Info.DirectoryPath & "\" &
TextBox6.Text 'PATH TO JAMPDED.EXE
p.StartInfo.Arguments = TextBox1.Text 'EXTRA PARAMETERS
p.StartInfo.CreateNoWindow = True
p.StartInfo.RedirectStandardInput = True
p.StartInfo.RedirectStandardOutput = True
p.StartInfo.UseShellExecute = False
p.Start()
input = p.StandardInput
out = p.StandardOutput
Dim thr As Thread = New Thread(AddressOf updatetextbox)
thr.IsBackground = True
thr.Start()
Sub updatetextbox()
While True
While Not out.EndOfStream
RichTextBox1.AppendText(out.ReadLine())
RichTextBox1.AppendText(vbNewLine)
End While
End While
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) _
Handles Button2.Click
input.WriteLine(TextBox4.Text)
TextBox4.Text = ""
input.Flush()
End Sub
When I am pressing Button2 that should write to STD/I text from my textbox, jampded.exe acts like it wasn't written. Also Output works well at startup, after that new lines are added rarely when there is a lot data in buffer.
Am I doing something wrong, or is it the application's fault?
For the standard input question:
Are you certain that the application you're starting is reading data from standard input (and not trapping keyboard events or something)? To test this, put some text that you're trying to send to the application in a text file (named, for example, commands.txt). Then send it to the application from a command prompt like so:
type commands.txt | jampded.exe
If that application reads those commands, then it is indeed reading from standard input. If it isn't, then redirecting standard input isn't going to help you get data to that application.
For the standard output question:
Instead of launching your own thread to handle the data coming from the other application, I would suggest doing something like this:
AddHandler p.OutputDataReceived, AddressOf OutputData
p.Start()
p.BeginOutputReadLine()
Private Sub AddLineToTextBox(ByVal line As String)
RichTextBox1.AppendText(e.Data)
RichTextBox1.AppendText(vbNewLine)
End Sub
Private Delegate Sub AddLineDelegate(ByVal line As String)
Private Sub OutputData(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
If IsNothing(e.Data) Then Exit Sub
Dim d As AddLineDelegate
d = AddressOf AddLineToTextBox
Invoke(d, e.Data)
End Sub
The Invoke call is required because OutputData may get called on a different thread, and UI updates all have to happen on the UI thread.
I've seen the same issue with data coming in batches when reading from the StandardOutput stream directly. The asynchronous read + event handler combo fixed it.

Simple software testing tool - VB.NET

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 prints the OUTPUT, and started building my tester, it should execute PROG.EXE output.txt, so PROG.EXE takes input from input.txt and prints the output to output.txt
but i failed, at first i tried Process.start then shell but nothing worked !
so i did this trick, the VB.NET codes generate a batch file with this codes PROG.EXE output.txt, but again i failed, though the VB.NET created the batch file and executes too, but nothing happened ! but when i manually run the batch file i got success !
i tried executing the batchfile then sendkey the VBCR/LF/CRLF still nothing happens !
whats wrong ?
My VB.NET Code, i am using 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
And this is my C code
#include<stdio.h>
#include<conio.h>
void main()
{
int x;
scanf("%d",&x);
printf("%d",(x*x));
}
my program runs perfectly when i run prog.exe <input.txt> output.txt in console
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
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