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

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)

Related

Workaround mutually exclusive "UseShellExecute" and "RedirectStandardOutput"

I need a workaround that will have the same effect as using True on both of the mutually exclusive UseShellExecute and RedirectStandardOutput.
The reason I need this is because I want to execute my perl script as I would through a CMD.exe:
perl perlcompare.pl <file1> <file2> <file3>
Noting that putting "perl" in front there seems to be optional as the file is already a .pl file.
I would like to have access to output the run gives me, as there might be error messages that are important to the user (e.g. missing files). Is there another way to achieve this?
Dim myProcess As New System.Diagnostics.Process
myProcess.StartInfo.WorkingDirectory = "K:\Engineering\Temp\perl"
myProcess.StartInfo.UseShellExecute = True
myProcess.StartInfo.FileName = "perlcompare.pl"
myProcess.StartInfo.Arguments = """" & MasterFile & """" & " " & """" & MasterOutput & """" & " " & """" & ComparisonsOutput & """"
myProcess.StartInfo.RedirectStandardOutput = True
myProcess.Start()
Dim sOutput As String
Using ProcessStreamReader As System.IO.StreamReader = myProcess.StandardOutput
sOutput = ProcessStreamReader.ReadToEnd()
End Using
MessageBox.Show(sOutput) 'txtOutput being the output textbox.
Quite new to the language and learning, so I will hound any clues you have for me.
I don't see why you want to set UseShellExecute to true. It needs to be false to allow redirection of the standard IO channels
If the location of the perl compiler executable is in PATH then you can just set FileName to perl. It's also better to use String.Format to build strings out of variables rather than use all those escaped quotes and concatenations
Dim myProcess As New System.Diagnostics.Process
myProcess.StartInfo.WorkingDirectory = "K:\Engineering\Temp\perl"
myProcess.StartInfo.UseShellExecute = False
myProcess.StartInfo.FileName = "perl"
myProcess.StartInfo.Arguments = String.Format(
"perlcompare.pl ""{0}"" ""{1}"" ""{2}""",
MasterFile,
MasterOutput,
ComparisonsOutput)
myProcess.StartInfo.RedirectStandardOutput = True
myProcess.Start()
If the location of the perl compiler isn't in the PATH then you can just put a fully-qualified file path into FileName

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

Displaying the output of Process.Start

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()

VB.NET - Problems trying to write a textfile

I have problems when trying to delete/create/write to this file.
The error:
The process cannot access the file 'C:\Users\Administrador\AppData\Local\Temp\PlayList_temp.txt' because it is being used by another process.
The highlighted lines by debugger:
If System.IO.File.Exists(Temp_file) = True Then System.IO.File.Delete(Temp_file)
System.IO.File.Create(Temp_file)
(Any of two, if I delete one line, the other line takes the same error id)
The sub:
Public Sub C1Button2_Click(sender As Object, e As EventArgs) Handles Button1.Click
If Not playerargs = Nothing Then
Dim Str As String
Dim Pattern As String = ControlChars.Quote
Dim ArgsArray() As String
Dim Temp_file As String = System.IO.Path.GetTempPath & "\PlayList_temp.txt"
Dim objWriter As New System.IO.StreamWriter(Temp_file)
Str = Replace(playerargs, " " & ControlChars.Quote, "")
ArgsArray = Split(Str, Pattern)
If System.IO.File.Exists(Temp_file) = True Then System.IO.File.Delete(Temp_file)
System.IO.File.Create(Temp_file)
For Each folder In ArgsArray
If Not folder = Nothing Then
Dim di As New IO.DirectoryInfo(folder)
Dim files As IO.FileInfo() = di.GetFiles("*")
Dim file As IO.FileInfo
For Each file In files
' command to writleline
'Console.WriteLine("File Name: {0}", file.Name)
'Console.WriteLine("File Full Name: {0}", file.FullName)
objWriter.Write(file.FullName)
objWriter.Close()
Next
End If
Next
If randomize.Checked = True Then
RandomiseFile(Temp_file)
End If
Process.Start(userSelectedPlayerFilePath, playerargs)
If autoclose.Checked = True Then
Me.Close()
End If
Else
MessageBox.Show("You must select at least one folder...", My.Settings.APPName)
End If
End Sub
First, File.Create creates or overwrite the file specified, so you don't need to Delete it before.
Second, initializing a StreamWriter as you do, blocks the file and therefore you can't recreate it after.
So, simply move the StreamWriter intialization after the File.Create, or better, remove altogether the File.Create and use the StreamWriter overload that overwrites the file
....
If Not playerargs = Nothing Then
....
Dim Temp_file As String = System.IO.Path.GetTempPath & "\PlayList_temp.txt"
Using objWriter As New System.IO.StreamWriter(Temp_file, false)
For Each folder In ArgsArray
If Not folder = Nothing Then
Dim di As New IO.DirectoryInfo(folder)
Dim files As IO.FileInfo() = di.GetFiles("*")
Dim file As IO.FileInfo
For Each file In files
' command to writleline
'Console.WriteLine("File Name: {0}", file.Name)
'Console.WriteLine("File Full Name: {0}", file.FullName)
objWriter.Write(file.FullName)
' objWriter.Close()
Next
End If
Next
End Using ' Flush, close and dispose the objWriter
....
Noticed also that you close the writer while still inside the loop, use the Using statement to close correctly the writer after the work is done.
The process cannot access the file 'C:\Users\Administrador\AppData\Local\Temp\PlayList_temp.txt' because it is being used by another process.
That means the file is opened or been used by another process.
Open your task manager and check if the file is there, then close it or simplex end the process.
I have had the same issue but I got it solved by closing the file.
Hope this helps!
From your details it seems that you are willing to delete if file exists and creates a new one.
I would suggest to remove this line:
System.IO.File.Create(Temp_file)
and move this line just over the streamwriter line:
If System.IO.File.Exists(Temp_file) = True Then System.IO.File.Delete(Temp_file)
Something like this would help you:
Partial code:
Dim Temp_file As String = System.IO.Path.GetTempPath & "\PlayList_temp.txt"
' Delete file if exists
If System.IO.File.Exists(Temp_file) = True Then System.IO.File.Delete(Temp_file)
' Create file for write.
Dim objWriter As New System.IO.StreamWriter(Temp_file)
Str = Replace(playerargs, " " & ControlChars.Quote, "")
ArgsArray = Split(Str, Pattern)
...
...
...

Wait for batch file to close before continuing - VB.net

I'm trying to run a batch file via VB and I need to wait for it to complete/exit before progressing. The issue I believe I am having is that when a batch file is executed, it opens cmd.exe and not the batch file.
This is what I am executing with VB
My.Computer.FileSystem.DeleteFile(My.Application.Info.DirectoryPath & "\PingCheck\machines.txt")
FileCopy(My.Application.Info.DirectoryPath & "\machines.txt", My.Application.Info.DirectoryPath & "\PingCheck\machines.txt")
Dim psi As New ProcessStartInfo(My.Application.Info.DirectoryPath & "\PingCheck\go.bat")
psi.RedirectStandardError = True
psi.RedirectStandardOutput = True
psi.CreateNoWindow = False
psi.WindowStyle = ProcessWindowStyle.Hidden
psi.UseShellExecute = False
Dim process As Process = process.Start(psi)
process.WaitForExit()
ProgressBar1.Value = ProgressBar1.Value + 2
FileCopy(My.Application.Info.DirectoryPath & "\PingCheck\machines.txt", My.Application.Info.DirectoryPath & "\machines.txt")
'My.Computer.FileSystem.DeleteFile(My.Application.Info.DirectoryPath & "\ping.bat")
MsgBox("Ping Check Complete")
The problem im having is that it will just delete ping.bat before it completes.
How do I go about monitoring the process from the batch file I call. Then once it exits, continue with the script?
RHicke shows a nice example of how to run a batch process in VB.NET here, Run batch file in vb.net?.
To expand, you should use the function WaitForExit() to wait for the process to complete.
Dim psi As New ProcessStartInfo("Path TO Batch File")
psi.RedirectStandardError = True
psi.RedirectStandardOutput = True
psi.CreateNoWindow = False
psi.WindowStyle = ProcessWindowStyle.Hidden
psi.UseShellExecute = False
Dim process As Process = Process.Start(psi)
process.WaitForExit()
You could use the System.Diagnostics.Process class to start the batch file. The process reference will give you access to the property HasExited (and more interesting information). The HasExited property indicates whether a process has completed.
var process = System.Diagnostics.Process.Start(new ProcessStartInfo
{
FileName = "batch file path",
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false,
Arguments = "parameters if applicable",
CreateNoWindow = true
});
while(!process.HasExited)
{
// obviously do some clever here to wait
}
Code is in C# but the principle should work in VB.NET
I've done something similar before. This code invokes RoboCopy from within VB.Net, using the System.Diagnostics.Process (mentioned by rivethead_).
Dim proc As System.Diagnostics.Process = New System.Diagnostics.Process()
proc.EnableRaisingEvents = False
proc.StartInfo.FileName = "d:\robocopy\robocopy"
proc.StartInfo.Arguments = strSrcDir & " " & strDestDir & " " & strFile & " " & My.Settings.robocopyFlags
proc.Start()
proc.WaitForExit()
Otherwise, what is the ping.bat doing? Is it just doing a "ping" command? If so, maybe you could invoke that with a System.Diagnostics.Process (instead of invoking a .bat file to do it). That might give you some more control over your process.