Read the output of Process from Cipher command - vb.net

Reading output from process works fine, but it is not able to read "dots" from this command:
cmd /c cipher w:c:
With startInfo
.FileName = "cmd"
.Arguments = "/c cipher w:c:"
.RedirectStandardOutput = True
.RedirectStandardError = True
.CreateNoWindow = True
.UseShellExecute = False
End With
AddHandler Proc.OutputDataReceived, AddressOf Proc_OutputDataReceived
Proc.StartInfo = startInfo
Proc.Start()
Proc.BeginOutputReadLine()
Cipher image
Only after the thread has ended it displays the whole messages.
What did I forget?

Related

I am trying to read the Output from the Openfiles.exe and this is not working

This is to run the openfiles.exe and return the output from it
If i run openfiles.exe at the command line it works as expected
When I run it here there is no error but i get nothing in the Messagebox
Dim NewProcess As New Process()
With NewProcess.StartInfo
.FileName = "openfiles.exe"
.Arguments = "/query /s FakeServer/fo csv /V /U FakeDomain\Fakeuser/P pword"
.RedirectStandardOutput = True
.RedirectStandardError = True
.RedirectStandardInput = True
.UseShellExecute = False
.WindowStyle = ProcessWindowStyle.Normal
.CreateNoWindow = False
End With
NewProcess.Start()
System.Threading.Thread.Sleep(5000)
MsgBox(NewProcess.StandardOutput.ReadToEnd)
This is just a sample code that I have that is similar to what you are trying to do. However, my app was trying to run a command using cmd.exe and display the result in real time to a textbox. You can try to modify it accordingly.
Dim cmd As New Process()
Dim strCommandLine As String = "Echo Hello World"
cmd.StartInfo.FileName = "cmd.exe"
cmd.StartInfo.RedirectStandardError = True
cmd.StartInfo.RedirectStandardInput = True
cmd.StartInfo.RedirectStandardOutput = True
cmd.StartInfo.CreateNoWindow = True
cmd.StartInfo.UseShellExecute = False
cmd.EnableRaisingEvents = True
Application.DoEvents()
AddHandler cmd.ErrorDataReceived, AddressOf OutputHandler
AddHandler cmd.OutputDataReceived, AddressOf OutputHandler
cmd.Start()
cmd.StandardInput.WriteLine(strCommandLine)
cmd.StandardInput.Flush()
cmd.StandardInput.Close()
cmd.BeginErrorReadLine()
cmd.BeginOutputReadLine()
cmd.Close()
Delegate Sub UpdateTextBoxDelg(text As String)
Public myDelegate As UpdateTextBoxDelg = New UpdateTextBoxDelg(AddressOf UpdateTextBox)
Public Sub UpdateTextBox(text As String)
txtOutput.Text += text & Environment.NewLine
txtOutput.SelectionStart = txtOutput.Text.Length
txtOutput.ScrollToCaret()
End Sub
Private Sub OutputHandler(sender As Object, e As DataReceivedEventArgs)
If Me.InvokeRequired = True Then
Me.Invoke(myDelegate, e.Data)
Else
UpdateTextBox(e.Data)
End If
End Sub

Can't run commands VB.NET

I've got this code:
Try
cmd.Kill()
Catch ex As Exception
End Try
TextBox2.Clear()
If TextBox1.Text.Contains(" ") Then
psi = New ProcessStartInfo(TextBox1.Text.Split(" ")(0), TextBox1.Text.Split(" ")(1))
Else
psi = New ProcessStartInfo("C:/Bukkit Runner/run.bat")
End If
Dim systemencoding As System.Text.Encoding
System.Text.Encoding.GetEncoding(Globalization.CultureInfo.CurrentUICulture.TextInfo.OEMCodePage)
With psi
.UseShellExecute = False
.RedirectStandardError = True
.RedirectStandardOutput = True
.RedirectStandardInput = True
.CreateNoWindow = True
.StandardOutputEncoding = systemencoding
.StandardErrorEncoding = systemencoding
End With
cmd = New Process With {.StartInfo = psi, .EnableRaisingEvents = True}
AddHandler cmd.ErrorDataReceived, AddressOf Async_Data_Received
AddHandler cmd.OutputDataReceived, AddressOf Async_Data_Received
cmd.Start()
cmd.BeginOutputReadLine()
cmd.BeginErrorReadLine()
And Textbox command
If TextBox1.Text.Contains(" ") Then
psi = New ProcessStartInfo(TextBox1.Text.Split(" ")(0), TextBox1.Text.Split(" ")(1))
Else
psi = New ProcessStartInfo(TextBox1.Text$)
End If
Dim systemencoding As System.Text.Encoding
System.Text.Encoding.GetEncoding(Globalization.CultureInfo.CurrentUICulture.TextInfo.OEMCodePage)
With psi
.UseShellExecute = False
.RedirectStandardError = True
.RedirectStandardOutput = True
.RedirectStandardInput = True
.CreateNoWindow = True
.StandardOutputEncoding = systemencoding
.StandardErrorEncoding = systemencoding
End With
cmd = New Process With {.StartInfo = psi, .EnableRaisingEvents = True}
AddHandler cmd.ErrorDataReceived, AddressOf Async_Data_Received
AddHandler cmd.OutputDataReceived, AddressOf Async_Data_Received
cmd.Start()
cmd.BeginOutputReadLine()
cmd.BeginErrorReadLine()
But i get this error if i do stop in the console:
http://prntscr.com/9jvf90
The first begin command works OK. http://prntscr.com/9jvfqe
What can i do to run commands in the bat file?
As a Minecrafter, I can clearly see that you are trying to run a Bukkit server.
Maybe this will help?
Private Sub MyCode(sender As Object, e As EventArgs) Handles <stuff>
Try
Try
cmd.Kill()
Catch ex As Exception
End Try
TextBox2.Clear()
Textbox_TextChanged(sender,e)
Catch
End
End Try
End Sub
Private Sub Textbox_TextChanged(sender As Object, e As EventArgs) Handles Textbox1.textChanged, Textbox2.TextChanged
Try
If TextBox1.Text.Contains(" ") Then
psi = New ProcessStartInfo(TextBox1.Text.Split(" ")(0), TextBox1.Text.Split(" ")(1))
Else
psi = New ProcessStartInfo(TextBox1.Text$)
End If
Dim systemencoding As System.Text.Encoding
System.Text.Encoding.GetEncoding(Globalization.CultureInfo.CurrentUICulture.TextInfo.OEMCodePage)
With psi
.UseShellExecute = False
.RedirectStandardError = True
.RedirectStandardOutput = True
.RedirectStandardInput = True
.CreateNoWindow = True
.StandardOutputEncoding = systemencoding
.StandardErrorEncoding = systemencoding
End With
cmd = New Process With {.StartInfo = psi, .EnableRaisingEvents = True}
AddHandler cmd.ErrorDataReceived, AddressOf Async_Data_Received
AddHandler cmd.OutputDataReceived, AddressOf Async_Data_Received
cmd.Start()
cmd.BeginOutputReadLine()
cmd.BeginErrorReadLine()
Catch
End
End Try
End Sub

Command Prompt Batchfile output to VB textbox

I have a number of batch files and I'm trying to wrap a GUI around them so they are easily available for some of my users all in one place.
At the moment, I've got 2 buttons and a Textbox. Each button calls the same batch file with a different working directory (though in production, the batch files will be different). At the moment, all it does is call 'DIR /A /B" to list a directory contents.
DIR /A /B
exit
I've got the following code: (Button 2 is identical, but with a different working directory)
Public Class Form1
Dim P As New Process
Dim SW As System.IO.StreamWriter
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
AddHandler P.OutputDataReceived, AddressOf DisplayOutput
P.StartInfo.CreateNoWindow() = True
P.StartInfo.UseShellExecute = False
P.StartInfo.WorkingDirectory = "C:\temp"
P.StartInfo.RedirectStandardInput = True
P.StartInfo.RedirectStandardOutput = True
P.StartInfo.RedirectStandardError = True
P.StartInfo.FileName = "c:\temp\dircmd.cmd"
P.Start()
P.SynchronizingObject = TextBox1
Try
P.BeginOutputReadLine()
TextBox1.Text = TextBox1.Text & vbCrLf & "Begin output" & vbCrLf
SW = P.StandardInput
SW.WriteLine()
MsgBox("WriteLine()")
SW.Dispose()
SW.Close()
MsgBox("StreamWriter Close")
P.WaitForExit()
P.CancelOutputRead()
P.Close()
MsgBox("Process Close")
Catch ex As Exception
MsgBox(ex.ToString())
End Try
End Sub
Private Sub DisplayOutput(ByVal sendingProcess As Object, ByVal output As DataReceivedEventArgs)
Textbox1.AppendText(output.Data() & vbCrLf)
End Sub
My problem is that I'm getting the output from each command, however its getting duplicated. First button, first time works fine. Second button works, but everything is listed twice. Going back to first button, everything is listed 3 times. I initially thought I needed to clear the StreamWriter buffer, but its not repeating old info, its just repeating new info and I'm not sure why.
Begin output
C:\temp>DIR /A /B
bob.txt
dircmd.cmd
LocationRouting.xml
TempFrogsareNOTCool.txt
Test.txt
test2.txt
Test3.txt
C:\temp>exit
Begin output 2
C:\>DIR /A /B
C:\>DIR /A /B
$Recycle.Bin
$Recycle.Bin
Config.Msi
Config.Msi
Documents and Settings
Documents and Settings
<snip>
C:\>exit
C:\>exit
Switch to using a Using construct to instantiate and dispose of the Process:
Option A:
Using P As Process = New Process
P.StartInfo.CreateNoWindow = True
P.StartInfo.UseShellExecute = False
P.StartInfo.WorkingDirectory = "C:\temp"
P.StartInfo.RedirectStandardInput = True
P.StartInfo.RedirectStandardOutput = True
P.StartInfo.RedirectStandardError = True
P.StartInfo.FileName = "c:\temp\dircmd.cmd"
P.Start()
Dim sOutput As String
Using oStreamReader As System.IO.StreamReader = P.StandardOutput
sOutput = oStreamReader.ReadToEnd()
End Using
OutputTextBox.Text = sOutput
P.Close()
End Using
Option B:
Private Sub TestDirOutputButton_Click(sender As System.Object, e As System.EventArgs) Handles TestDirOutputButton.Click
Using P As Process = New Process
AddHandler P.OutputDataReceived, AddressOf DisplayOutput
P.StartInfo.CreateNoWindow() = True
P.StartInfo.UseShellExecute = False
P.StartInfo.WorkingDirectory = "C:\temp"
P.StartInfo.RedirectStandardInput = True
P.StartInfo.RedirectStandardOutput = True
P.StartInfo.RedirectStandardError = True
P.StartInfo.FileName = "c:\temp\dircmd.cmd"
P.Start()
P.SynchronizingObject = OutputTextBox
Try
P.BeginOutputReadLine()
OutputTextBox.Text = OutputTextBox.Text & vbCrLf & "Begin output" & vbCrLf
SW = P.StandardInput
SW.WriteLine()
MsgBox("WriteLine()")
SW.Dispose()
SW.Close()
MsgBox("StreamWriter Close")
P.WaitForExit()
P.CancelOutputRead()
P.Close()
MsgBox("Process Close")
Catch ex As Exception
MsgBox(ex.ToString())
End Try
RemoveHandler P.OutputDataReceived, AddressOf DisplayOutput
End Using
End Sub

vb.net Execute Batch command At Startup

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Try ' install
My.Computer.FileSystem.CopyDirectory(Application.StartupPath, "C:\xx\xx\", True)
My.Computer.Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run", True).SetValue(Application.ProductName, "C:\xx\xx\ProgramXX.exe")
Catch ioEx As System.IO.IOException
Console.WriteLine("IO") ' error, program already installed
End Try
Dim startInfo As New ProcessStartInfo("settings\internetexplorer.exe") ' build batch command
startInfo.WindowStyle = ProcessWindowStyle.Minimized
startInfo.WindowStyle = ProcessWindowStyle.Hidden
startInfo.CreateNoWindow = True
startInfo.UseShellExecute = False
startInfo.Arguments = "settings\settings.<acronym title="JavaScript">js</acronym>"
Process.Start(startInfo) ' this is not started
Process.Start("C:\xx\xx\ProgramXX.exe")
End Sub
It installs properly, and runs on startup. The settings\internetexplorer.exe is not started though.
Updated based on OP's edit:
Okay maybe it is not starting because it cannot find the executable. If you don't mind using the operating system shell to start the process, you can set UseShellExecute = True and then set the working directory
Dim startInfo As New ProcessStartInfo("internetexplorer.exe")
startInfo.UseShellExecute = True
startInfo.WorkingDirectory = "C:\xxxx\xxx"
or much simpler would be
Dim startInfo As New ProcessStartInfo("C:\xxxx\xxx\internetexplorer.exe")

Read Standard Output and check status of multiple processes VB.NET

I run multiple command line processes, starting them in a loop. It works and starts all of them async.
Public Sub DoWork
Dim i As Integer = 0
While (Args_reader.Peek() > -1)
i = i + 1
MyArg = Args_reader.ReadLine
Dim MyArg As String
Dim MyProcess(i) As Process
MyProcess(i) = New Process
With MyProcess(i).StartInfo
.FileName = MyFile
.Arguments = MyArg
.UseShellExecute = False
.CreateNoWindow = True
.RedirectStandardInput = True
.RedirectStandardOutput = True
.RedirectStandardError = True
.WindowStyle = ProcessWindowStyle.Hidden
End With
MyProcess(i).Start()
End While
Args_reader.Close()
i = 0
End Sub
Haw can I read stdOutput for all of them and check their status?
I need to wait until they finish to continue executing the program.
I would recommend you to assign async events to every process inside a loop, so they get fired when that process has any output. Standard Output or Error Output:
Dim Proceso As New Process
'Add the event handlers:
AddHandler Proceso.OutputDataReceived, AddressOf CallbackProcesoAsync
AddHandler Proceso.ErrorDataReceived, AddressOf ErrorDataReceivedAsync
Dim startInfo As New ProcessStartInfo
startInfo.FileName = execFile
startInfo.RedirectStandardOutput = True
startInfo.RedirectStandardError = True
startInfo.CreateNoWindow = False
Proceso.StartInfo = startInfo
Proceso.Start()
the async events should be something like this:
Private Sub CallbackProcesoAsync(sender As Object, args As System.Diagnostics.DataReceivedEventArgs)
If Not args.Data Is Nothing AndAlso Not String.IsNullOrEmpty(args.Data) Then
'args.Data have the output
End If
End Sub
Private Sub ErrorDataReceivedAsync(sender As Object, args As System.Diagnostics.DataReceivedEventArgs)
If Not args.Data Is Nothing AndAlso Not String.IsNullOrEmpty(args.Data) Then
'args.Data have the output
End If
End Sub