I've set up my filesystemwatcher, but I'm getting odd results. I've found that if I put a complete path of a directory, and set include subdirectories, then changes are channeled as they should. But what I've tried to do unsuccessfully is set my "C:\" drive as the path with include subdirectories.
Are there restrictions on using the main drive as a path?
I've tried every syntax of it I could, but no success. Just wondering if there's something there I don't know...comments welcome :)
Here's pertinent code if anyone wants to take a look at it. Suggestions would be great:
<PermissionSet(SecurityAction.Demand, Name:="FullTrust")>
Private Sub WatchFolders()
Dim myConn As New OleDbConnection("Provider = Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\kgene\source\repos\Test Program\Test Program\Resources\BakDb.accdb")
MessageBox.Show("setting up watch folders")
watcher = New FileSystemWatcher With {.NotifyFilter = NotifyFilters.DirectoryName Or NotifyFilters.FileName Or NotifyFilters.Attributes}
watcher.Path = "c:\"
watcher.IncludeSubdirectories = True
watcher.EnableRaisingEvents = True
AddHandler watcher.Changed, AddressOf LogChange
AddHandler watcher.Created, AddressOf LogChange
AddHandler watcher.Deleted, AddressOf LogChange
AddHandler watcher.Renamed, AddressOf LogChangeR
End Sub
Private Sub LogChange(ByVal source As Object, ByVal e As FileSystemEventArgs)
Dim myConn As New OleDbConnection("Provider = Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\kgene\source\repos\Test Program\Test Program\Resources\BakDb.accdb")
Dim cmd As New OleDbCommand
chkCnt = 0
Try
str = "SELECT Base, Target FROM Backup"
cmd.Connection = myConn
cmd.CommandText = str
myConn.Open()
Dim lstReader As OleDbDataReader = cmd.ExecuteReader()
If cntPlns = 0 Then
myConn.Close()
Exit Sub
End If
lstReader.Read()
Do Until chkCnt = cntPlns
If lstReader.Item(0).ToString().ToLower() = Path.GetDirectoryName(e.FullPath).ToString.ToLower() Or lstReader.Item(1).ToString().ToLower() = Path.GetDirectoryName(e.FullPath).ToString().ToLower() Then
If e.ChangeType = IO.WatcherChangeTypes.Changed Then
MessageBox.Show("first item changed")
End If
If e.ChangeType = IO.WatcherChangeTypes.Created Then
MessageBox.Show("first item create")
End If
If e.ChangeType = IO.WatcherChangeTypes.Deleted Then
MessageBox.Show("first item delete")
End If
End If
If cntPlns = 0 Then
myConn.Close()
Exit Sub
End If
lstReader.Read()
chkCnt += 1
Loop
chkCnt = 0
myConn.Close()
Catch ex As Exception
chkCnt = 0
myConn.Close()
MessageBox.Show("There was a problem conncecting to the database to watch your folders")
Exit Sub
End Try
End Sub
I moved the
watcher.EnableRaisingEvents = True
after the code that register the events as Jimi suggested. This solve the problem setting up the watched folders to register events as expected.
Related
Im doing a school project. and I was testing a login form for my app. I'm trying separately from my login form and a profile pic form. I have successfully managed to save the image to the access database but I have had quite a few problems trying to display it on a textbox on my form.
This is the whole app code:
Imports System.Data.OleDb
Imports System.IO
Public Class Form2
Dim con As OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\geral\source\repos\BD de imagenes\BD de imagenes\DBImagenes.mdb")
Dim cmd As New OleDbCommand
Dim sql As String
Dim da As New OleDb.OleDbDataAdapter
Dim result As Integer
Private Sub saveimage(sql As String)
Try
Dim arrimage() As Byte
Dim mstream As New System.IO.MemoryStream
PictureBox1.Image.Save(mstream, System.Drawing.Imaging.ImageFormat.Png)
arrimage = mstream.GetBuffer()
Dim Filesize As UInt32
Filesize = mstream.Length
mstream.Close()
con.Open()
cmd = New OleDbCommand
With cmd
.Connection = con
.CommandText = sql
.Parameters.AddWithValue("#Imagen", arrimage)
.Parameters.Add("#Nombre", OleDbType.VarChar).Value = TextBox1.Text
.ExecuteNonQuery()
End With
Catch ex As Exception
MsgBox(ex.Message)
Finally
con.Close()
End Try
End Sub
'End Try
Public conex As New OleDbConnection()
Public Sub conexion()
conex.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\geral\source\repos\BD de imagenes\BD de imagenes\DBImagenes.mdb"
conex.Open()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles BTNGuardar.Click
sql = "Insert into TBImg (Imagen, Nombre) Values (#Imagen, #Nombre)"
'sql = "Insert into TBImg (Imagen) Values (#Imagen)"
saveimage(sql)
MsgBox("Image has been saved in the database")
End Sub
Private Sub BtnExaminar_Click(sender As Object, e As EventArgs) Handles BtnExaminar.Click
OpenFileDialog1.Filter = "Imagenes JPG|*.jpg|Imagenes PNG|*.png"
OpenFileDialog1.RestoreDirectory = True
If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
PictureBox1.Image = Image.FromFile(OpenFileDialog1.FileName)
End If
End Sub
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
End Sub
Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
Try
With OpenFileDialog1
'CHECK THE SELECTED FILE IF IT EXIST OTHERWISE THE DIALOG BOX WILL DISPLAY A WARNING.
.CheckFileExists = True
'CHECK THE SELECTED PATH IF IT EXIST OTHERWISE THE DIALOG BOX WILL DISPLAY A WARNING.
.CheckPathExists = True
'GET AND SET THE DEFAULT EXTENSION
.DefaultExt = "jpg"
'RETURN THE FILE LINKED TO THE LNK FILE
.DereferenceLinks = True
'SET THE FILE NAME TO EMPTY
.FileName = ""
'FILTERING THE FILES
.Filter = "(*.jpg)|*.jpg|(*.png)|*.png|(*.jpg)|*.jpg|All files|*.*"
'SET THIS FOR ONE FILE SELECTION ONLY.
.Multiselect = False
'SET THIS TO PUT THE CURRENT FOLDER BACK TO WHERE IT HAS STARTED.
.RestoreDirectory = True
'SET THE TITLE OF THE DIALOG BOX.
.Title = "Select a file to open"
'ACCEPT ONLY THE VALID WIN32 FILE NAMES.
.ValidateNames = True
If .ShowDialog = DialogResult.OK Then
Try
PictureBox1.Image = Image.FromFile(OpenFileDialog1.FileName)
Catch fileException As Exception
Throw fileException
End Try
End If
End With
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Exclamation, Me.Text)
End Try
End Sub
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
conexion()
PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
End Sub
Private Sub Label1_Click(sender As Object, e As EventArgs) Handles Label1.Click
End Sub
Private Sub BtnBuscar_Click(sender As Object, e As EventArgs) Handles BtnBuscar.Click
Dim arrimage() As Byte
Dim conn As New OleDb.OleDbConnection
Dim Myconnection As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\geral\source\repos\BD de imagenes\BD de imagenes\DBImagenes.mdb"
conn.ConnectionString = Myconnection
conn.Open()
sql = "Select * from TBImg where Nombre=" & (TBBuscar.Text)
Dim cmd As New OleDbCommand
With cmd
.Connection = conex
.CommandText = sql
End With
Dim publictable As New DataTable
Try
da.SelectCommand = cmd
da.Fill(publictable)
TextBox1.Text = publictable.Rows(1).Item("Nombre").ToString
arrimage = publictable.Rows(1).Item("Imagen")
Dim mstream As New System.IO.MemoryStream(arrimage)
PictureBox1.Image = Image.FromStream(mstream)
Catch ex As Exception
MsgBox(ex.Message)
Finally
da.Dispose()
conn.Close()
End Try
End Sub
End Class
the relevant part is at Private Sub BtnBuscar_Click.
I'm trying to search in a textbox for the name that I saved the image with. but I haven't had success all I get is the error of the title.
this is how my database looks like the images are saved as an ole object
This is the error I get
I was following this tutorial https://www.youtube.com/watch?v=zFdjp39mfhQ
but he didn't quite explain how to use the:
TextBox1.Text = publictable.Rows(0).Item(1)
arrimage = publictable.Rows(0).Item(1)'
don't know if it's the cause of the issue.
instructions. The reason why my code looks different is that I was trying to stuff to see if I could make it work.
I have tried to search for answers and people suggest that I may have put the table name wrong or the column but I copied the name exactly how it is in the table with ctrl + c and ctrl + v.
what I want is that when I type the name in the column name of the database that it brings the designated picture stored as ole object onto my desired picture box on my form app.
Needless to say, I'm not that experienced with vb.net and SQL, Acces. I'm just following tutorials for being able to complete the project.
Do not declare connections or commands or datareaders at the class level. They all need to have their Dispose methods called. Using blocks will have the declare, closing and disposing even if there is an error. Streams also need Using blocks.
Defaults for an OpenFiledialog
Multiselect is False
CheckFileExists is True
CheckPathExists is True
DereferenceLinks is True
ValidateNames is True
FileName is ""
Unless you are getting paid by the line, it is unnecessary to reset these values to their defaults.
I have alerted your Filter to exclude All Files. You also had jpg appearing twice.
I declared a variable to hold the file extension, PictureFormat, of the image file so you could provide the proper parameter for ImageFormat.
When you retrieve the image field from the database it comes as an Object. To get the Byte() a DirectCast should work.
Private PictureFormat As String
Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
FillPictureBoxFromFile()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles BTNGuardar.Click
Try
saveimage()
Catch ex As Exception
MessageBox.Show(ex.Message)
Exit Sub
End Try
MsgBox("Image has been saved in the database")
End Sub
Private cnStr As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\geral\source\repos\BD de imagenes\BD de imagenes\DBImagenes.mdb"
Private Sub saveimage()
Dim arrimage() As Byte
Using mstream As New System.IO.MemoryStream
If PictureFormat.ToLower = ".png" Then
PictureBox1.Image.Save(mstream, System.Drawing.Imaging.ImageFormat.Png)
ElseIf PictureFormat.ToLower = ".jpg" Then
PictureBox1.Image.Save(mstream, System.Drawing.Imaging.ImageFormat.Jpeg)
End If
arrimage = mstream.GetBuffer()
Dim Filesize As Long
Filesize = mstream.Length
End Using
Using con As New OleDbConnection(cnStr),
cmd As New OleDbCommand("Insert into TBImg (Imagen, Nombre) Values (#Imagen, #Nombre)", con)
With cmd
.Parameters.Add("#Imagen", OleDbType.Binary).Value = arrimage
.Parameters.Add("#Nombre", OleDbType.VarChar).Value = TextBox1.Text
con.Open()
.ExecuteNonQuery()
End With
End Using
End Sub
Private Sub BtnExaminar_Click(sender As Object, e As EventArgs) Handles BtnExaminar.Click
FillPictureBoxFromFile()
End Sub
Private Sub BtnBuscar_Click(sender As Object, e As EventArgs) Handles BtnBuscar.Click
Dim dt As DataTable
Try
dt = GetDataByName(TBBuscar.Text)
Catch ex As Exception
MessageBox.Show(ex.Message)
Exit Sub
End Try
TextBox1.Text = dt(0)("Nombre").ToString
Dim arrimage = DirectCast(dt(0)("Imagen"), Byte())
Dim mstream As New System.IO.MemoryStream(arrimage)
PictureBox1.Image = Image.FromStream(mstream)
End Sub
Private Function GetDataByName(name As String) As DataTable
Dim dt As New DataTable
Using conn As New OleDb.OleDbConnection(cnStr),
cmd As New OleDbCommand("Select * from TBImg where Nombre= #Buscar", conn)
cmd.Parameters.Add("#Buscar", OleDbType.VarChar).Value = TBBuscar.Text
conn.Open()
Using reader = cmd.ExecuteReader
dt.Load(reader)
End Using
End Using
Return dt
End Function
Private Sub FillPictureBoxFromFile()
With OpenFileDialog1
.Filter = "(*.jpg)|*.jpg|(*.png)|*.png"
.RestoreDirectory = True
.Title = "Select a file to open"
If .ShowDialog = DialogResult.OK Then
PictureBox1.Image = Image.FromFile(OpenFileDialog1.FileName)
End If
PictureFormat = Path.GetExtension(OpenFileDialog1.FileName)
End With
End Sub
Here is my code:
Public Sub RegisterNotification()
Dim conStr As String = ConfigurationManager.ConnectionStrings("sqlConString").ConnectionString
Dim sqlCommand As String = "SELECT [ID],[Description], [CreateDate], [NoteTypeID] from [note].[Notes]"
Using con As New SqlConnection(conStr)
Dim cmd As New SqlCommand(sqlCommand, con)
If con.State <> System.Data.ConnectionState.Open Then
con.Open()
End If
cmd.Notification = Nothing
Dim sqlDep As New SqlDependency(cmd)
AddHandler sqlDep.OnChange, AddressOf sqlDep_OnChange
Using reader As SqlDataReader = cmd.ExecuteReader()
End Using
End Using
End Sub
Private Sub sqlDep_OnChange(sender As Object, e As SqlNotificationEventArgs)
If e.Type = SqlNotificationType.Change Then
Dim sqlDep As SqlDependency = TryCast(sender, SqlDependency)
'Dim id
RemoveHandler sqlDep.OnChange, AddressOf sqlDep_OnChange
If e.Info = 1 Then
Dim notificationHub = GlobalHost.ConnectionManager.GetHubContext(Of NotificationHub)()
notificationHub.Clients.All.notify("added")
RegisterNotification()
'GetNotificationList(0, 1)
End If
End If
End Sub
Global.asax code:
Protected Sub Application_Start()
Try
Dim _obj As New DAL.sap.Register
_obj.Register()
AreaRegistration.RegisterAllAreas()
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters)
RouteConfig.RegisterRoutes(RouteTable.Routes)
BundleConfig.RegisterBundles(BundleTable.Bundles)
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "webpages_UserProfile", "UserId", "UserName", True)
SqlDependency.Start(con)
Catch ex As Exception
End Try
End Sub
Protected Sub Session_Start(sender As Object, e As EventArgs)
Try
Dim NC As New NotificationComponent()
NC.RegisterNotification()
Catch ex As Exception
End Try
End Sub
Protected Sub Application_End()
Try
SqlDependency.Stop(con)
Catch ex As Exception
End Try
End Sub
Startup code:
<Assembly: OwinStartupAttribute(GetType(www.Startup))>
Namespace www
Partial Public Class Startup
Public Sub Configuration(app As IAppBuilder)
app.MapSignalR()
End Sub
End Class
End Namespace
My problem is sqldep_onchange not always firing. Sometimes it works perfectly but sometimes nothing happen. is it a bug or something like that? what i'm doing wrong?
It looks like everything is correct, although my VB is extremely rusty, I would try removing the if on the SqlNotificationType and see if that helps, it might be too restricting, I would also make sure that its actually the dependency that is not firing rather an something else swallowing it later on down the chain. Also what happens if your TryCast fails? Since its not in a try it will not throw and your notifications will not fire and your new handler will not be added.
Private Sub sqlDep_OnChange(sender As Object, e As SqlNotificationEventArgs)
If e.Type = SqlNotificationType.Change Then
Dim sqlDep As SqlDependency = TryCast(sender, SqlDependency)
'Dim id
Delete --> ***RemoveHandler sqlDep.OnChange, AddressOf sqlDep_OnChange*** <--Delete
If e.Info = 1 Then
Dim notificationHub = GlobalHost.ConnectionManager.GetHubContext(Of NotificationHub)()
notificationHub.Clients.All.notify("added")
RegisterNotification()
'GetNotificationList(0, 1)
End If
End If
End Sub
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
I have a function in VB.net that has this code inside:
filename = TextBox5.Text
FileOpen(1, filename, OpenMode.Input)
There is an OpenFileDialog1, and when a file is chosen it puts the file path/name in TextBox5
When i click a button, it reads in the CSV file selected using OpenFileDialog1
I then have another function that has this code inside:
TextBox5.Text = "C:\file.csv"
In this second function, the OpenFileDialog1 is not used as the function puts the file path/name in TextBox5
Its working fine when i choose the file and upload it using a OpenFileDialog1 but when it puts the filename in TextBox5 automatically (the second function), its not reading in the data
I would simply create a method and call that from wherever i need it:
Public Sub OpenFile(Dim file As String)
' insert your code here '
End Sub
Sub FistButton_Click(Object sender, EventArgs e)
OpenFile(TextBox5.Text)
End Sub
Sub SecondButton_Click(Object sender, EventArgs e)
TextBox5.Text = "C:\file.csv"
OpenFile(TextBox5.Text)
End Sub
Private watcher As System.IO.FileSystemWatcher = Nothing
Public Sub AvisCsvMonitorStart(ByVal avisSettings As String)
watcher = Nothing
watcher = New System.IO.FileSystemWatcher
'CSV監視
'watcher.Path = "C:\Users\core01\Desktop\Mango\WinBin"
watcher.Path = My.Application.Info.DirectoryPath
watcher.Filter = "VitalData.csv" 'Monitor *.txt files, set to "" to monitor all
watcher.NotifyFilter = System.IO.NotifyFilters.LastWrite Or System.IO.NotifyFilters.CreationTime
watcher.IncludeSubdirectories = False
AddHandler watcher.Changed, AddressOf watcher_Changed
AddHandler watcher.Created, AddressOf watcher_Changed
AddHandler watcher.Deleted, AddressOf watcher_Changed
AddHandler watcher.Renamed, AddressOf watcher_Renamed
watcher.EnableRaisingEvents = True
End Sub
'変更がある場合はCSVを監視する
Private Sub watcher_Changed(ByVal source As System.Object, _
ByVal e As System.IO.FileSystemEventArgs)
Select Case e.ChangeType
Case System.IO.WatcherChangeTypes.Changed
'CSVからデータを取得
Call ParseCSV(e.FullPath)
Case System.IO.WatcherChangeTypes.Created
MessageBox.Show("Has been Created", e.Name, MessageBoxButtons.OKCancel)
Case System.IO.WatcherChangeTypes.Deleted
MessageBox.Show("Has been Deleted", e.Name, MessageBoxButtons.OKCancel)
End Select
End Sub
Private Sub watcher_Renamed(ByVal source As System.Object, _
ByVal e As System.IO.RenamedEventArgs)
MessageBox.Show("Has been Renamed", e.Name, MessageBoxButtons.OKCancel)
End Sub
'CSVからデータを取得
Private Sub ParseCSV(ByVal path As String)
Dim mIndex As Integer
Dim mDate As String
Dim mTime As String
Using MyReader As New Microsoft.VisualBasic.FileIO.
TextFieldParser(path)
MyReader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
MyReader.Delimiters = New String() {","}
MyReader.ReadLine() ' skip header
While Not MyReader.EndOfData
Try
Dim fields = MyReader.ReadFields() 'contains all the items
mIndex = fields(0)
Dim dateTime = fields(3).Split(" ")
mDate = dateTime(0)
mTime = dateTime(1)
Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
MsgBox("Line " & ex.Message &
" is invalid. Skipping")
End Try
End While
End Using
End Sub
I'm trying to redirect the output from a command-line application in VB.NET, and for some reason it fails to redirect the output. Here's my code:
Dim myProcess As Process = New Process
myProcess.StartInfo.FileName = "g++"
myProcess.StartInfo.Arguments = CMDLineCommand
myProcess.StartInfo.UseShellExecute = False
myProcess.StartInfo.RedirectStandardOutput = True
myProcess.StartInfo.RedirectStandardError = True
myProcess.StartInfo.CreateNoWindow = True
myProcess.Start()
Dim output As String = myProcess.StandardOutput.ReadToEnd
myProcess.WaitForExit()
CMDLineOutputTextBox.Text = output
Does anybody know why it's not being redirected? Thanks in advance!
-Neil
EDIT: Here's my full code, in case there's anything weird with my syntax:
Dim myProcess As Process = New Process
myProcess.StartInfo.FileName = "g++"
myProcess.StartInfo.Arguments = CMDLineCommand
myProcess.StartInfo.UseShellExecute = False
myProcess.StartInfo.RedirectStandardOutput = True
myProcess.StartInfo.RedirectStandardError = True
myProcess.StartInfo.CreateNoWindow = True
myProcess.EnableRaisingEvents = True
AddHandler myProcess.OutputDataReceived, AddressOf GotData
myProcess.Start()
CMDLineOutputTextBox.Text = ""
myProcess.BeginOutputReadLine()
Later on...
Private Sub GotData(sendingProcess As Object, outLine As DataReceivedEventArgs)
If Not String.IsNullOrEmpty(outLine.Data) Then
SetText(outLine.Data)
End If
End Sub
Delegate Sub SetTextCallback(value As String)
Private Sub SetText(ByVal value As String)
If Me.CMDLineOutputTextBox.InvokeRequired Then
Dim d As New SetTextCallback(AddressOf SetText)
Me.Invoke(d, New Object() {value})
Else
Me.CMDLineOutputTextBox.Text += value + Environment.NewLine
End If
End Sub
Anything weird?
Your method will work, provided by the time you hit the line where you read the output to the end, all of the output is there. Since you are using g++, I assume that may not always be the case. You will probably be better off using the OutputDataReceived Event and capturing the data from that.
Dim myProcess As Process = New Process
myProcess.StartInfo.FileName = "ping"
myProcess.StartInfo.Arguments = "www.google.com"
myProcess.StartInfo.UseShellExecute = False
myProcess.StartInfo.RedirectStandardOutput = True
myProcess.StartInfo.RedirectStandardError = True
myProcess.StartInfo.CreateNoWindow = True
myProcess.EnableRaisingEvents = True
AddHandler myProcess.OutputDataReceived, AddressOf GotData
myProcess.Start()
myProcess.BeginOutputReadLine()
Then you handle the event like this:
Private Sub GotData(sendingProcess As Object, outLine As DataReceivedEventArgs)
If Not String.IsNullOrEmpty(outLine.Data) Then
SetText(outLine.Data)
End If
End Sub
Delegate Sub SetTextCallback(value As String)
Private Sub SetText(ByVal value As String)
If Me.TextBox3.InvokeRequired Then
Dim d As New SetTextCallback(AddressOf SetText)
Me.Invoke(d, New Object() {value})
Else
Me.TextBox3.Text += value + Environment.NewLine
End If
End Sub
I have noticed the waitforExit seems to make the code lock during the invoke.required check. When I take out the waitforexit it works.