Displaying the output of Process.Start - vb.net

I have a Process.Start command that I would like to see the output of, but the new window is opening and closing too quickly for me to see anything. Here is the code I have so far that I'm working with:
System.Diagnostics.Process.Start(Environment.GetEnvironmentVariable("VS110COMNTOOLS") & "..\Ide\MSTEST.EXE", "/Testsettings: """ & rwSettings & "" & " /Testcontainer: """ & rwContainer & "" & " /Resultsfile: """ & rwResults & "")
Unfortunately as I try to debug this if I allow this to run it flashes up the window but doesn't let me see what the error is, or if it's running successfully at all. I'm using VS2012 so I might just not be looking at the right view when I'm debugging.

Here is some code taen out of the middle of some logic, so it is not standalone. You can use ProcessStartInfo() and Process() to have more control:
Dim start_info As New ProcessStartInfo("sqlcmd", cmd)
start_info.UseShellExecute = False
start_info.CreateNoWindow = True
start_info.RedirectStandardOutput = True
start_info.RedirectStandardError = True
' Make the process and set its start information.
Dim proc As New Process()
proc.StartInfo = start_info
Dim dt As Date = Now()
' Start the process.
proc.Start()
' Attach to stdout and stderr.
Dim std_out As StreamReader = proc.StandardOutput() ' will not continue until process stops
Dim std_err As StreamReader = proc.StandardError()
' Retrive the results.
Dim sOut As String = std_out.ReadToEnd()
Dim sErr As String = std_err.ReadToEnd()

Related

Using cmd in VB, using commands and receiving output

I need to know, if you could help me, how to insert commands in vb then they run in cmd and i get the output.
I need to do "net localgroup Administradores a58465 /add" and get the error message if there is one.
Solution: `Dim myProcess As Process = New Process
Dim s As String
myProcess.StartInfo.FileName = "c:\windows\system32\cmd.exe"
myProcess.StartInfo.UseShellExecute = False
myProcess.StartInfo.CreateNoWindow = True
myProcess.StartInfo.RedirectStandardInput = True
myProcess.StartInfo.RedirectStandardOutput = True
myProcess.StartInfo.RedirectStandardError = True
myProcess.Start()
Dim sIn As System.IO.StreamWriter = myProcess.StandardInput
Dim sOut As System.IO.StreamReader = myProcess.StandardOutput
Dim sErr As System.IO.StreamReader = myProcess.StandardError
'sIn.AutoFlush = True
sIn.Write("cls" & System.Environment.NewLine)
sIn.Write("net user" & System.Environment.NewLine)
sIn.Write("exit" & System.Environment.NewLine)
s = sOut.ReadToEnd()
If Not myProcess.HasExited Then
myProcess.Kill()
End If
LB1.Text = s
LB1.Visible = True
sIn.Close()
sOut.Close()
sErr.Close()
myProcess.Close()`
Check out Process.Start. http://msdn.microsoft.com/en-us/library/0w4h05yb(v=vs.110).aspx
Also look for the ProcessStartInfo class, which will give you options on how to kick off an external process.
Console input and output can be made available to your program through ProcessStartInfo.

How do i read the output from a batch file in a vb program

thanks in advance i just want to know if theres a way to read the output from a running batch file in a vb.net program. Thanks!
As one commenter above mentions, you can run the batch file in a shell within your VB.NET program and then read the directed output. I have done this exactly in previous project.
Here is a code snippet which shows how you can do it:
Dim outputFile As String = """" & Path.GetTempFileName & """"
Dim batchCommand As String = """C:\Path\To\MyFile.bat"">" & outputFile
Dim cmdProcess As New Process
With cmdProcess
.StartInfo = New ProcessStartInfo("cmd.exe", "/C " & batchCommand)
With .StartInfo
.CreateNoWindow = True
.UseShellExecute = False
End With
.Start()
.WaitForExit()
End With
' This is the output from the batch file.
Dim batchOutput As String = My.Computer.FileSystem.ReadAllText(outputFile)

How to Copy CMD Results into Textbox on VB.Net Project

I'm working on a Project by VB.net and i'm using CMD to excute commands i want to Know how to copy the Results of the CMD into a textbox on my Main Form
Take a look at the accepted answer here: Get the output of a shell Command in VB.net. That is probably what you need.
Also, here is a version of the code that puts the result into the textbox:
Dim oProcess As New Process()
Dim oStartInfo As New ProcessStartInfo("ApplicationName.exe", "arguments")
oStartInfo.UseShellExecute = False
oStartInfo.RedirectStandardOutput = True
oProcess.StartInfo = oStartInfo
oProcess.Start()
Dim sOutput As String
Using oStreamReader As System.IO.StreamReader = oProcess.StandardOutput
sOutput = oStreamReader.ReadToEnd()
End Using
txtOutput.Text = sOutput 'txtOutput being the output textbox.
I hope this helps.
Dim proc As New Process
proc.StartInfo.FileName = "C:\ipconfig.bat"
proc.StartInfo.UseShellExecute = False
proc.StartInfo.RedirectStandardOutput = True
proc.Start()
proc.WaitForExit()
Dim output() As String = proc.StandardOutput.ReadToEnd.Split(CChar(vbLf))
For Each ln As String In output
RichTextBox1.AppendText(ln & vbNewLine)
lstScan.Items.Add(ln & vbNewLine)
Next
'Created a file in batch with 2 lines as shown below:
echo off
ipconfig
' save this file as ipconfig.bat or whatever name u want.
' if you didn't want that you could use any command on there like this:
echo off
dir/s
or
echo off
cd\
dir/s
pause

VB.Net process exits as soon as I attempt to read standard output or error

Initial Problem
I apologize if this issue has been raised and addressed elsewhere; I searched this site, and Google at large without any luck.
I'm trying to write a simple VB.Net Windows Forms Application to allow a user to run the Windows File Compare program (fc.exe) with a very simple GUI ("browse" buttons to select files, checkboxes to select modifiers, and a textbox for the output).
The problem is that whenever I try to read the standard output or error from the process, it immediately stops, and nothing is output. I've verified that the process arguments are correct by setting "createnowindow" to False and not redirecting Output or Errors.
To see if the process is actually running or not, I put a "while" loop after proc.start:
Do While proc.HasExited = False
textbox.AppendText(i & vbNewLine)
i += 1
Loop
If the process runs normally, I get a count up to about 80 or 90. If I do anything at all with the standardoutput or standarderror, the textbox only shows the initial value of "0". By "anything at all", I mean assigning the proc.StandardOutput.ReadToEnd to a variable. If I use proc.StandardOutput.Peek, it returns a -1 and the loop remains at 0.
I've noticed that if I only redirect either Output or Error (but not both), and I enable the process to open a new window, the new window is empty and immediately exits (even if I'm not attempting to read the redirected stream in my code), whereas if neither is redirected, it displays a few pages of results, then exits. I don't know if this is normal, or if the File Compare executable is somehow mixing the Output and Error streams to generate its output, or if something like that is even possible.
I'm extremely new to coding in general (I've been working with VB.net for about a month, and that's the extent of my programming experience), so my I'm aware that my troubleshooting and assumptions may be completely off base, and I appreciate any assistance anyone can provide. As it is, I'm completely floundering, and my inexperience is making it difficult to look for alternatives (for instance, I can't figure out how to correctly handle asynchronous output). For reference, here's my embarrassingly clunky code as it currently stands:
Dim cmdinput As String = """" & file1path & """" & " " & """" & file2path & """"
Dim cmdmods As String = " "
Dim i As Integer = 0
Dim proc As New Process
proc.StartInfo.CreateNoWindow = True
proc.StartInfo.UseShellExecute = False
proc.StartInfo.FileName = "C:\Windows\System32\fc.exe"
proc.StartInfo.Arguments = cmdinput & cmdmods
proc.StartInfo.RedirectStandardOutput = True
proc.StartInfo.RedirectStandardError = True
proc.Start()
proc.StandardOutput.ReadToEnd()
Do While proc.HasExited = False
scanbox.AppendText(i & vbNewLine)
i += 1
Loop
Possible Solution
After Hans Passant pointed out that I should be seeing errors, if nothing else, I messed around with my code and was able to get a result, though a less than optimal one. Instead of running FC.exe directly, I ran CMD.exe. I had tried this before with no luck, but that's because CMD.exe doesn't accept "fc " as process.startinfo.arguments.
I passed the "fc " to cmd.exe with proc.standardinput.writeline(). At this point I was able to read CMD.exe's redirected output. I still have no idea why I can't directly read FC.exe, but this is a pretty good band-aid in the meantime. On the off chance that anyone else feels the need to add a GUI to a perfectly good command-line executable and runs into problems, here's my code:
Public Sub compare()
Dim cmdinput As String = "fc " & """" & file1path & """" & " " & """" & file2path & """"
Dim cmdmods As String = " "
Dim proc As New Process
proc.StartInfo.CreateNoWindow = True
proc.StartInfo.UseShellExecute = False
proc.StartInfo.FileName = "C:\Windows\System32\cmd.exe"
proc.StartInfo.Arguments = cmdinput & cmdmods
proc.StartInfo.RedirectStandardOutput = True
proc.StartInfo.RedirectStandardError = True
proc.StartInfo.RedirectStandardInput = True
proc.Start()
proc.StandardInput.WriteLine(cmdinput)
proc.StandardInput.Close()
scanbox.AppendText(proc.StandardOutput.ReadToEnd)
proc.WaitForExit()
proc.Close()
proc.Dispose()
End Sub
I Greatly appreciate the patience from Hans Passant and Dan Verdolino in offering suggestions to my rambling question. I've been hammering my head against a wall for a week trying to kludge together some way of doing this.
Solution
Instead of running FC.exe directly, I ran CMD.exe. I had tried this before with no luck, but that's because CMD.exe doesn't accept "fc (args)" as process.startinfo.arguments.
I passed the "fc (args)" to cmd.exe with proc.standardinput.writeline(). At this point I was able to read CMD.exe's redirected output. I still have no idea why I can't directly read FC.exe's output or errors, but this is a pretty good band-aid in the meantime. On the off chance that anyone else feels the need to add a GUI to a perfectly good command-line executable and runs into problems, here's my code:
Public Sub compare()
Dim cmdinput As String = "fc " & """" & file1path & """" & " " & """" & file2path & """"
Dim cmdmods As String = " "
Dim proc As New Process
proc.StartInfo.CreateNoWindow = True
proc.StartInfo.UseShellExecute = False
proc.StartInfo.FileName = "C:\Windows\System32\cmd.exe"
proc.StartInfo.Arguments = cmdinput & cmdmods
proc.StartInfo.RedirectStandardOutput = True
proc.StartInfo.RedirectStandardError = True
proc.StartInfo.RedirectStandardInput = True
proc.Start()
proc.StandardInput.WriteLine(cmdinput)
proc.StandardInput.Close()
scanbox.AppendText(proc.StandardOutput.ReadToEnd)
proc.WaitForExit()
proc.Close()
proc.Dispose()
End Sub
Private Delegate Sub InvokeWithString(ByVal text As String)
Public Sub StartFC()
Private psi As ProcessStartInfo
Private cmd As Process
Dim CMDINPUT As String = "fc " & """" & file1path & """" & " " & """" & file2path & """"
Dim FileToHit As String = "c:\windows\system32\fc.exe "
psi = New ProcessStartInfo(FileToHit)
Dim systemencoding As System.Text.Encoding = _
System.Text.Encoding.GetEncoding(Globalization.CultureInfo.CurrentUICulture.TextInfo.OEMCodePage)
With psi
.Arguments = CMDINPUT
.UseShellExecute = False ' Required for redirection
.RedirectStandardError = True
.RedirectStandardOutput = True
.RedirectStandardInput = True
.CreateNoWindow = True
.StandardOutputEncoding = systemencoding
.StandardErrorEncoding = systemencoding
End With
' EnableraisingEvents is required for Exited event
cmd = New Process With {.StartInfo = psi, .EnableRaisingEvents = True}
AddHandler cmd.ErrorDataReceived, AddressOf Async_Data_Received
AddHandler cmd.OutputDataReceived, AddressOf Async_Data_Received
AddHandler cmd.Exited, AddressOf CMD_Exited
cmd.Start()
pID1 = cmd.Id
cmd.BeginOutputReadLine()
cmd.BeginErrorReadLine()
Me.txtInputStringIn.Select() ' textbox where you can send more commands.
End Sub
'This event fires when process exited
Private Sub CMD_Exited(ByVal sender As Object, ByVal e As EventArgs)
'Me.Close()
MessageBox.Show("Process is exited.")
End Sub
'This part calls when Output received
Private Sub Async_Data_Received(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
Me.Invoke(New InvokeWithString(AddressOf Sync_Output), e.Data)
End Sub
Private Sub Sync_Output(ByVal text As String)
'an output textbox will show the output of the command prompt.
txtOutPut.AppendText(text & Environment.NewLine)
txtOutPut.ScrollToCaret()
End Sub

starting a process in cmd window

I have to start a process in a cmd window.
But in cases like shown because of some error cmd window just flashes and I can't see what happens. It would be the best if cmd window stay opened until some keypress or similar.
Dim q As String = Chr(34)
Dim p As New Process
With p.StartInfo
.FileName = q & whereis7z & "\7z.exe" & q
.Arguments = " e " & q & tempArch & fNameStr & q & " -y"
.WindowStyle = ProcessWindowStyle.Normal
.CreateNoWindow = False
.WorkingDirectory = tempArch
Debug.Print(.FileName & .Arguments)
End With
p.Start()
If p.ExitCode <> 0 Then
MsgBox(p.ExitCode, MsgBoxStyle.Critical)
End If
Is here any way to keep cmd window opened until keypress to see what's wrong with my 'StartInfo' because 'ExitCode' is not enough.
Alternatively, you could redirect the standard output of the window in order to capture the program output.
p.StartInfo.RedirectStandardOutput = True
Then just read in what the program has output so you can display it yourself,
Dim Output as String = p.StandardOutput.ReadToEnd
you should execute the cmd.com application instead of your program directly.
If you try from the start menu "cmd /k dir", you will receive the directory listing and the window will remain open.
I think you must pass your application in parameters (arguments)
Hope this helps
Serge