Progress bar is not working in BackgroundWorker VB.Net - vb.net

I'm trying to get a progress bar to show while a method is being executed. I've called BackgroundWorker1.RunWorkerAsync() from a button. Then in the DoWork I call the method to run "runCopyFiles". I update the progress in ProgressChanged, and exit with RunWorkerCompleted. I'm not sure what I have wrong. I've searched the net for tutorials and examples on how to do this and have created the code from them. But the progress bar doesn't show.
Code For executing from button
Private Sub btnExecuteFileCopy_Click(sender As Object, e As EventArgs) Handles btnExecuteFileCopy.Click
Me.Refresh()
If Not BackgroundWorker1.IsBusy = True Then
BackgroundWorker1.RunWorkerAsync()
End If
End Sub
Code for BackGroundWorker
Private Sub BackgroundWorker1_DoWork(sender As Object, e As ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
BackgroundWorker1.WorkerReportsProgress = True
Const Max As Integer = 1000
For i = 1 To Max
'' do something
'' (I put a sleep to simulate time consumed)
Threading.Thread.Sleep(100)
'' report progress at regular intervals
BackgroundWorker1.ReportProgress(CInt(100 * i / Max), "Running..." & i.ToString)
'' check at regular intervals for CancellationPending
If BackgroundWorker1.CancellationPending Then
BackgroundWorker1.ReportProgress(CInt(100 * i / Max), "Cancelling...")
Exit For
End If
Next
runCopyFiles()
End Sub
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
ProgressBar1.Value = e.ProgressPercentage
lblStatus.Text = e.ProgressPercentage.ToString() + " %"
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
If e.Cancelled = True Then
MsgBox(" Operation Cancelled ")
ProgressBar1.Value = 0
lblStatus.Text = ""
ElseIf e.Error IsNot Nothing Then
MsgBox(e.Error.Message)
Else
MsgBox(" Process Complete ")
End If
End Sub
Code RunCopy
Private Sub runCopyFiles()
Application.UseWaitCursor = True
Application.DoEvents()
Me.Refresh()
Dim sFileToFind As String
Dim location As String
Dim File As String
'Dim createReportFldr As String
'Dim createXMLFldr As String
'Dim createImgFldr As String
'Directory Files are located in
location = txtFolderPath.Text
'Directory files are to copied into
MoveLocation = CopyToPath
createImgFldr = MoveLocation & "\Figures"
createReportFldr = MoveLocation & "\Reports"
createXMLFldr = MoveLocation & "\XML files"
'Create Figures Folder
If Not IO.Directory.Exists(createImgFldr) Then
IO.Directory.CreateDirectory(createImgFldr)
' MsgBox("folder created" & createFolder)
End If
'Create Reports folder
If Not IO.Directory.Exists(createReportFldr) Then
IO.Directory.CreateDirectory(createReportFldr)
'MsgBox("folder created" & createReportFldr)
End If
'Create XML folder
If Not IO.Directory.Exists(createXMLFldr) Then
IO.Directory.CreateDirectory(createXMLFldr)
' MsgBox("folder created" & createFolder)
End If
orphanedFiles = MoveLocation & "\Reports\OrphanedFilesItems.txt"
' Create or overwrite the file.
System.IO.File.Create(orphanedFiles).Dispose()
ListofFiles = MoveLocation & "\Reports\ListOfFiles.txt"
' Create or overwrite the file.
System.IO.File.Create(ListofFiles).Dispose()
MissingFiles = MoveLocation & "\Reports\MissingGraphicList.txt"
' Create or overwrite the file.
System.IO.File.Create(MissingFiles).Dispose()
Dim FILE_NAME As String
FILE_NAME = txtFileName.Text
Dim objReader As New System.IO.StreamReader(FILE_NAME)
Dim sFile As String
Do While objReader.Peek() <> -1
File = objReader.ReadLine()
sFileToFind = location & "\" & File & "*.*"
sFile = File
Dim paths() As String = IO.Directory.GetFiles(location, sFile, IO.SearchOption.AllDirectories)
If paths.Count = 0 Then
System.IO.File.AppendAllText(orphanedFiles, sFile & vbNewLine)
' Debug.Print(File)
'If System.IO.File.Exists(orphanedFiles) = True Then
' Dim objWriter As New System.IO.StreamWriter(orphanedFiles, IO.FileMode.Append)
' objWriter.WriteLine(File)
' objWriter.Close()
'Else
'MsgBox("Creating Orphaned File Now. ")
'End If
Else
For Each pathAndFileName As String In paths
Dim moveToFolder As String
If System.IO.File.Exists(pathAndFileName) = True Then
Dim sRegLast As String = pathAndFileName.Substring(pathAndFileName.LastIndexOf("\") + 1)
Dim toFileLoc As String
'MsgBox("sRegLast " & sRegLast)
' fileLoc = MoveLocation & sRegLast
moveToFolder = MoveLocation & "\XML files\" & sRegLast
toFileLoc = createXMLFldr & "\" & sRegLast
'MsgBox("FileLoc " & fileLoc)
'if toFileLoc = XML file exists move it into the XML files folder
If System.IO.File.Exists(toFileLoc) = False Then
System.IO.File.Copy(pathAndFileName, moveToFolder)
System.IO.File.AppendAllText(ListofFiles, sRegLast & vbNewLine)
End If
End If
Next
End If
Loop
'MsgBox("Files have been moved")
Call CreateGraphicsFunction(Nothing, System.EventArgs.Empty)
Call getImages()
MsgBox("Process Complete", MsgBoxStyle.DefaultButton1)
Application.UseWaitCursor = False
Application.DoEvents()
' Me.Close()
End Sub

If you loop while there are more lines in your file, there's no way to know how many total lines there are, and that is a crucial component in the percent calculation for the progress bar:
percent = 100 * currentFile / totalFiles
So instead, we can read all lines up front and iterate over them. This should be your runCopyFiles
Dim fileNames = System.IO.File.ReadAllLines(FILE_NAME)
For i = 0 To fileNames.Count() - 1
Dim fileName = fileNames(i)
sFileToFind = location & "\" & fileName & "*.*"
Dim paths = IO.Directory.GetFiles(location, fileName, IO.SearchOption.AllDirectories)
If Not paths.Any() Then
System.IO.File.AppendAllText(orphanedFiles, fileName & vbNewLine)
Else
For Each pathAndFileName As String In paths
If System.IO.File.Exists(pathAndFileName) = True Then
Dim sRegLast = pathAndFileName.Substring(pathAndFileName.LastIndexOf("\") + 1)
Dim toFileLoc = System.IO.Path.Combine(createXMLFldr, sRegLast)
Dim moveToFolder = System.IO.Path.Combine(moveLocation, "XML files", sRegLast)
'if toFileLoc = XML file exists move it into the XML files folder
If System.IO.File.Exists(toFileLoc) = False Then
System.IO.File.Copy(pathAndFileName, moveToFolder)
System.IO.File.AppendAllText(ListofFiles, sRegLast & vbNewLine)
End If
End If
Next
End If
BackgroundWorker1.ReportProgress(100 * i / fileNames.Count())
Next
That is where the progress should be reported.
And all you should have in your DoWork is this
Private Sub BackgroundWorker1_DoWork(sender As Object, e As ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
runCopyFiles()
End Sub
You never need Application.DoEvents, and if you find that you do need it, then you are doing something wrong. DoWork calls code on a background thread which
Shouldn't access the UI without invoking calls on the UI thread
In turn doesn't block the UI from updating...
... which is really why you use it - so you can run processing code behind the UI without slowing it down.
In total, here are all the things you should remember to do
Don't access UI from background thread
Use Using to automatically dispose IDisposable objects
Use System.IO.Path.Combine to combine paths instead of using string concatenation
Don't call runCopyFiles 101 times
BackgroundWorker1.ReportProgress is meant to be called when you are doing work
If booleanValue = True Then is redundant, just do If booleanValue Then

Related

The process cannot access the file 'path' because it is being used by another process when use FileSystemWatcher

I have trouble creating excel or word files in folders that need to be tracked. If creating continuously using a regular new file right at the home directory trace, it will report an error like this.
I use the filesystemwatcher to keep track of the file
Here is my code
Public Sub Createee(sender As Object, e As FileSystemEventArgs)
Try
Dim x = e.Name
List1.Add(x)
Dim path As String = e.FullPath
Dim i = InStr(path, ".")
Dim y = InStr(path, "~$")
If File.Exists(path) Then
List.Add(path)
End If
If path.EndsWith(".txt") Or path.EndsWith(".docx") Or path.EndsWith(".xlsx") Or path.EndsWith(".csv") Then
If System.IO.Directory.Exists(path) Then
LbxWatching.Items.Add(Now.ToLocalTime & " - " & path & " - " & e.ChangeType.ToString)
List.Add(path)
'My.Computer.FileSystem.CopyDirectory(TbxFrom.Text, TbxTo.Text, True)
System.IO.File.Copy(path, TbxTo.Text.ToString & "\" & e.Name, True)
End If
End If
If path.EndsWith(".txt") Or path.EndsWith(".docx") Or path.EndsWith(".xlsx") Or path.EndsWith(".csv") Then
If i > 0 And y = 0 Then
If Not path.Substring(path.Length - 4) = ".tmp" And Not path.Substring(path.Length - 4) = ".TMP" Then
LbxWatching.Items.Add(Now.ToLocalTime & " - " & path & " - " & e.ChangeType.ToString)
List.Add(path)
'My.Computer.FileSystem.CopyDirectory(TbxFrom.Text, TbxTo.Text, True)
My.Computer.FileSystem.CopyFile(path, TbxTo.Text.ToString & "\" & e.Name, True)
End If
End If
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
List.Clear()
List1.Clear()
End Sub
Private Sub FileWatcher_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
Dim appsettings = ConfigurationManager.AppSettings
Dim result As String
For Each result In appsettings
If result = "Key0" Then
TbxFrom.Text = appsettings("Key0")
ElseIf result = "Key1" Then
TbxTo.Text = appsettings("Key1")
End If
Next
MapDrive("X", TbxTo.Text)
Watcher = New FileSystemWatcher()
Watcher.Path = TbxFrom.Text
Watcher.Filter = "*.*"
Watcher.IncludeSubdirectories = True
Watcher.NotifyFilter = NotifyFilters.LastAccess Or NotifyFilters.LastWrite Or NotifyFilters.FileName Or NotifyFilters.DirectoryName
AddHandler Watcher.Changed, AddressOf Modify
AddHandler Watcher.Created, AddressOf Createee
AddHandler Watcher.Deleted, AddressOf Delete
AddHandler Watcher.Renamed, AddressOf ChangeName
Watcher.EnableRaisingEvents = True
CheckForIllegalCrossThreadCalls = False
LbxWatching.Items.Clear()
List = New ArrayList()
List1 = New ArrayList()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
This only happens when I create files in the monitoring folder, other things like editing, deleting files, or copying a bunch of files from elsewhere are not corrupted.

Get percentage of files copied from a list

I have an app that copies files in a list to a new directory. I'm trying to get the progress bar to work but my formula results with a System.OverflowException: Arithmetic operation resulted in an over flow. I've looked at other examples using file copying but they are centered on using the source folder divided by destination folder. Mines a little bit different because I'm using files in a list.
Thank you for the help.
Code
Dim progress = fileCount * 100 / fileList.Count()
BackgroundWorker1.ReportProgress(progress)
Code for getting file Count
Dim FILE_NAME As String
FILE_NAME = txtFileName.Text
Dim fileNames = System.IO.File.ReadAllLines(FILE_NAME)
fCount = 0
For i = 0 To fileNames.Count() - 1
Dim fileName = fileNames(i)
sFileToFind = location & "\" & fileName & "*.*"
Dim paths = IO.Directory.GetFiles(location, fileName, IO.SearchOption.AllDirectories)
If Not paths.Any() Then
System.IO.File.AppendAllText(orphanedFiles, fileName & vbNewLine)
Else
For Each pathAndFileName As String In paths
If System.IO.File.Exists(pathAndFileName) = True Then
sRegLast = pathAndFileName.Substring(pathAndFileName.LastIndexOf("\") + 1)
Dim toFileLoc = System.IO.Path.Combine(createXMLFldr, sRegLast)
Dim moveToFolder = System.IO.Path.Combine(MoveLocation, "XML files", sRegLast)
'if toFileLoc = XML file exists move it into the XML files folder
If System.IO.File.Exists(toFileLoc) = False Then
System.IO.File.Copy(pathAndFileName, moveToFolder)
System.IO.File.AppendAllText(ListofFiles, sRegLast & vbNewLine)
fCount = fCount + 1
XMLFilename = (sRegLast) + vbCrLf
End If
End If
Next
End If
Dim srcCount = paths.Count()
If (paths.Count() = 0) Then
srcCount = 1
End If
Dim progress = CType(fCount * 100 / srcCount, Integer)
BackgroundWorker1.ReportProgress(progress)
Next
This for BackGroundWorker, I hope will this can resolve the trouble of the next call to update progress bar:
'This button1_click event to begin or stop async of backGrounedWorker
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
BackgroundWorker1.WorkerReportsProgress = True
BackgroundWorker1.WorkerSupportsCancellation = True
BackgroundWorker1.CancelAsync()
Try
BackgroundWorker1.RunWorkerAsync()
Catch ex As Exception
End Try
End Sub
'Here your backGroundProcess
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim FILE_NAME As String
FILE_NAME = txtFileName.Text 'can be changed
Dim fileNames = System.IO.File.ReadAllLines(FILE_NAME)
Dim Location As String = "C:\MyData\Folder1" 'can be changed
Dim moveToFolder As String = "C:\MyData\Folder2" 'can be changed
Dim fCount As Integer = 0
For Each fileName In fileNames
Dim paths = IO.Directory.GetFiles(Location, fileName,
IO.SearchOption.AllDirectories)
If paths.Count > 0 Then
Try
System.IO.File.Copy(paths(0), moveToFolder & "\" & fileName, True)
Catch ex As Exception
Debug.Print(ex.Message)
End Try
End If
For a = 1 To 100
Debug.Print(a.ToString)
Next
'If any request pending process will be stop (when Button1_click happen while process running (BackGroundWorker in Action))
If BackgroundWorker1.CancellationPending = True Then Exit For
fCount += 1
Dim Progress As Integer = Convert.ToInt32(fCount * 100 / fileNames.Count)
BackgroundWorker1.ReportProgress(progress)
Next
End Sub
'This will show you the progress in your progress bar
Private Sub bw1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
Me.ProgressBar1.Value = e.ProgressPercentage
End Sub
'Your Process Have Been Complete Here
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
MessageBox.Show("Finish")
End Sub
This last modification from me:
ListBox1.Items.Clear()
Dim FILE_NAME As String
FILE_NAME = "c:\YourFolder\YourFile.txt" 'can be changed
Dim fileNames = System.IO.File.ReadAllLines(FILE_NAME)
For Each MyFile In fileNames
ListBox1.Items.Add(MyFile)
Next
Dim Location As String = "C:\YourFolder1" 'can be changed
Dim moveToFolder As String = "C:\YourFolder2" 'can be changed
Dim fCount As Integer = 0
For Each fileName In fileNames
Dim paths = IO.Directory.GetFiles(Location, fileName,
IO.SearchOption.AllDirectories)
If paths.Count > 0 Then
Try
System.IO.File.Copy(paths(0), fileName)
Catch ex As Exception
End Try
End If
fCount += 1
Dim progress As Integer = Convert.ToInt32(fCount * 100 / fileNames.Count)
Next

Unable to cancel application

I have an application that copies files into different directories. As the application is running if I click the BtnExit_Click button nothing happens. I'm only able to exit out of the app after it has run through all the files to copy.
This is my code
Private Sub BtnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
BackgroundWorker1.CancelAsync()
Me.Close()
End Sub
Background Worker:
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
Me.txtImgCount.Text = iCount
Me.txtImgCount.Update()
Me.fileCount.Text = fCount
Me.fileCount.Update()
Me.txtTotal.Update()
Me.Label8.Text = statusText
Me.Label8.Update()
Application.DoEvents()
Try
Me.RichTextBox1.Text &= (fileFilename)
Application.DoEvents()
Catch ei As DivideByZeroException
Debug.WriteLine("Exception caught: {0}", ei)
Finally
End Try
Try
Me.RichTextBox1.Text &= (imgFilename)
Application.DoEvents()
Catch ea As DivideByZeroException
Debug.WriteLine("Exception caught: {0}", ea)
Finally
End Try
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
RunCopyFiles()
End Sub
Private Sub RunCopyFiles()
BackgroundWorker1.WorkerReportsProgress = True
Dim sFileToFind As String
Dim location As String
'Dim File As String
statusText = "Initiating"
status = "Initiating..."
'Directory Files are located in
location = txtFolderPath.Text
'Directory ICN files are located in
imgLocation = txtSearchICN.Text
'Directory files are to copied into
MoveLocation = CopyToPath
createImgFldr = MoveLocation & "\Figures"
createReportFldr = MoveLocation & "\Reports"
createXMLFldr = MoveLocation & "\XML files"
'Create Figures Folder
If Not IO.Directory.Exists(createImgFldr) Then
IO.Directory.CreateDirectory(createImgFldr)
' MsgBox("folder created" & createFolder)
End If
'Create Reports folder
If Not IO.Directory.Exists(createReportFldr) Then
IO.Directory.CreateDirectory(createReportFldr)
'MsgBox("folder created" & createReportFldr)
End If
'Create XML folder
If Not IO.Directory.Exists(createXMLFldr) Then
IO.Directory.CreateDirectory(createXMLFldr)
' MsgBox("folder created" & createFolder)
End If
'Text file with list of file names
Dim filesToCopy = txtFileName.Text
orphanedFiles = MoveLocation & "\Reports\OrphanedFilesItems.txt"
' Create or overwrite the file.
System.IO.File.Create(orphanedFiles).Dispose()
ListofGraphics = MoveLocation & "\Reports\ListOfGraphics.txt"
' Create or overwrite the file.
System.IO.File.Create(ListofGraphics).Dispose()
Dim removDupBuildLog = MoveLocation & "\Reports\RemvoeDup.txt"
Dim ListLog = MoveLocation & "\Reports\ListOfGraphics.txt"
ListofFiles = MoveLocation & "\Reports\ListOfFiles.txt"
' Create or overwrite the file.
System.IO.File.Create(ListofFiles).Dispose()
MissingFiles = MoveLocation & "\Reports\MissingGraphicList.txt"
' Create or overwrite the file.
System.IO.File.Create(MissingFiles).Dispose()
Dim FILE_NAME As String
FILE_NAME = txtFileName.Text
Dim fileNames = System.IO.File.ReadAllLines(FILE_NAME)
status = "Copying SGML\XML Files"
statusText = "Copying SGML\XML Files..."
fCount = 0
For i = 0 To fileNames.Count() - 1
Dim fileName = fileNames(i)
sFileToFind = location & "\" & fileName & "*.*"
Dim paths = IO.Directory.GetFiles(location, fileName, IO.SearchOption.AllDirectories)
If Not paths.Any() Then
System.IO.File.AppendAllText(orphanedFiles, fileName & vbNewLine)
Else
For Each pathAndFileName As String In paths
If System.IO.File.Exists(pathAndFileName) = True Then
Dim sRegLast = pathAndFileName.Substring(pathAndFileName.LastIndexOf("\") + 1)
Dim toFileLoc = System.IO.Path.Combine(createXMLFldr, sRegLast)
Dim moveToFolder = System.IO.Path.Combine(MoveLocation, "XML files", sRegLast)
'if toFileLoc = XML file exists move it into the XML files folder
If System.IO.File.Exists(toFileLoc) = False Then
System.IO.File.Copy(pathAndFileName, moveToFolder)
System.IO.File.AppendAllText(ListofFiles, sRegLast & vbNewLine)
Application.DoEvents()
fileFilename = (fileName) + vbCrLf
fCount = fCount + 1
'fileCount.Text = fCount
End If
End If
Next
End If
BackgroundWorker1.ReportProgress(100 * (i + 1) / fileNames.Count)
Next
CreateGraphicsFunction()
GetImages()
Application.UseWaitCursor = False
Application.DoEvents()
End Sub
If you look at the code example in the documentation for the BackgroundWorker Class you will see that it checks the worker.CancellationPending property every time through the loop.
So you'll need a couple of changes:
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
RunCopyFiles(worker, e)
End Sub
Private Sub RunCopyFiles(worker As BackgroundWorker, e As DoWorkEventArgs)
... other code here
For Each pathAndFileName As String In paths
... other code here
If worker.CancellationPending Then
e.Cancel = True
Exit Sub
End If
Next
Maybe put another check just after the ReportProgress(...) too.
Also, you will need to set backgroundWorker1.WorkerSupportsCancellation = True.
The Application.UseWaitCursor = False should not be in the worker - put it in the code that calls backgroundWorker1.RunWorkerAsync().
As LarsTech wrote in a comment, you should remove all calls to Application.DoEvents(): problems with it are listed in Use of Application.DoEvents().
Finally, make sure that you are using Option Strict On.

VB2010 read a csv in datagrid, update in grid and save to same csv

Created a procedure in VB2010 to read a csv-file in datagridviewer, update cells in grid and save to same csvfile
Opening the csvfile in the datagridviewer works fine,
Updating in the datagridviewer works fine also
But when I save the datagrid to a csv-file with the same name, I get an error message "The process Can not access the file because it is used by an other process".
But if I save it to an other filename it is ok.
Then I tried to copy the new file with the new filename back to the original filename.
I received still the same error message that I cant copy because the file is still in use.
Does anybody now how to solve this.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim fName As String = ""
OpenFileDialog1.InitialDirectory = "H:\Data\2014\Software\VB2010\"
OpenFileDialog1.Filter = "CSV files (*.csv)|*.CSV"
OpenFileDialog1.FilterIndex = 2
OpenFileDialog1.RestoreDirectory = True
If (OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK) Then
fName = OpenFileDialog1.FileName
End If
Me.TextBox1.Text = fName
Dim TextLine As String = ""
Dim SplitLine() As String
DataGridView1.ColumnCount = 5
DataGridView1.Columns(0).Name = "Name"
DataGridView1.Columns(1).Name = "Gender"
DataGridView1.Columns(2).Name = "Age"
DataGridView1.Columns(3).Name = "Ranking"
DataGridView1.Columns(4).Name = "Date"
If System.IO.File.Exists(fName) = True Then
Dim objReader As New System.IO.StreamReader(fName)
Do While objReader.Peek() <> -1
TextLine = objReader.ReadLine()
SplitLine = Split(TextLine, ",")
Me.DataGridView1.Rows.Add(SplitLine)
Loop
Else
MsgBox("File Does Not Exist")
End If
End Sub
Private Sub SaveGridDataInFile(ByRef fName As String)
'method called by button2
Dim I As Integer = 0
Dim j As Integer = 0
Dim cellvalue$
Dim rowLine As String = ""
Try
Dim objWriter As New System.IO.StreamWriter(fName, True)
For j = 0 To (DataGridView1.Rows.Count - 2)
For I = 0 To (DataGridView1.Columns.Count - 1)
If Not TypeOf DataGridView1.CurrentRow.Cells.Item(I).Value Is DBNull Then
cellvalue = DataGridView1.Item(I, j).Value
Else
cellvalue = ""
End If
rowLine = rowLine + cellvalue + ","
Next
objWriter.WriteLine(rowLine)
rowLine = ""
Next
objWriter.Close()
objWriter = Nothing
MsgBox("Text written to file")
Catch e As Exception
MessageBox.Show("Error occured while writing to the file." + e.ToString())
Finally
FileClose(1)
End Try
Call copy_file()
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
'çall method SaveGridDataInFile
SaveGridDataInFile(Me.TextBox1.Text)
' FileCopy("H:\Data\2014\Software\VB2010\datagr_ex2.csv", "H:\Data\2014\Software\VB2010\datagr_ex.csv")
End Sub
Sub copy_file()
Dim FileToDelete As String
FileToDelete = "H:\Data\2014\Software\VB2010\datagr_ex.csv"
If System.IO.File.Exists(FileToDelete) = True Then
System.IO.File.Delete(FileToDelete)
MsgBox("File Deleted")
End If
FileCopy("H:\Data\2014\Software\VB2010\datagr_ex2.csv", "H:\Data\2014\Software\VB2010\datagr_ex.csv")
End Sub
My guess is you need to close the StreamReader you use to load the file before you can reopen the file to save it. The StreamReader class implements IDisposable so you can use VB.Net's Using Statement to automatically close the file when you're finished reading, i.e.
If System.IO.File.Exists(fName) = True Then
Using objReader As New System.IO.StreamReader(fName)
Do While objReader.Peek() <> -1
TextLine = objReader.ReadLine()
SplitLine = Split(TextLine, ",")
Me.DataGridView1.Rows.Add(SplitLine)
Loop
End Using
Else
MsgBox("File Does Not Exist")
End If

How to Ignore Illegal Characters in Path when using StreamWriter?

Full code at bottom.
I've been getting an ArgumentException: "Illegal characters in path" whenever I attempt to save my text file in the program I've created.
My thoughts are that it has something to do with the directory path(path is chosen by user when prompted to open the file using an inputbox). My path on my computer being:
C:\Users\User\Desktop\HighScoreEditor
I've read tab characters can be the cause of this exception so my thoughts were maybe it's caused by the "\" in the directory path. I'm a 2nd year University Student so I may be completely wrong.
What I'm looking for is how to ignore this exception so that my file is saved, or a way to fix it so this exception does not occur.
My file is read from a directory path input by the user during an inputbox:
Dim message, title, defaultValue As String
Dim myValue As Object
Dim inFile As StreamReader
Dim strLine As String
' Set prompt.
message = "Enter a directory path to open your HighScore List."
' Set title.
title = "Which HighScore List should I open?"
defaultValue = "" ' Set default value.
' Display message, title, and default value.
myValue = InputBox(message, title, defaultValue)
' If user has clicked Cancel.
If myValue Is "" Then
Exit Sub
End If
Try
If File.Exists(myValue) = False Then
MessageBox.Show("Error: File/Directory Path """ & myValue & """ does not exist.")
ElseIf File.Exists(myValue) = True Then
inFile = File.OpenText(myValue)
Do While inFile.Peek <> -1
strLine = inFile.ReadLine()
txtScores.Text = txtScores.Text & vbCrLf & strLine
Loop
' Close the file.
inFile.Close()
End If
Catch ex As Exception
MessageBox.Show("Error: File/Directory Path """ & myValue & """ was found, however could not be opened." & vbCrLf & "" & vbCrLf & "Please make sure the list has a .txt file extension.")
End Try
Here is my code for my StreamWriter and save button:
Private Sub mnuFile_Save_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuFile_Save.Click
Dim outFile As StreamWriter
outFile = File.CreateText(txtScores.Text)
outFile.WriteLine(txtScores.Text)
outFile.Close()
End Sub
------FULL CODE BELOW------
Imports System.IO
Public Class frmHighScore_Editor
Dim strTxt As String = "Click File > Open to display your HighScore List Here."
Private Sub mnuFile_Exit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuFile_Exit.Click
' Terminates the program.
Me.Close()
End Sub
Private Sub mnuFile_Open_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuFile_Open.Click
Dim frmContinue As New frmContinue
frmContinue.ShowDialog()
Dim message, title, defaultValue As String
Dim myValue As Object
Dim inFile As StreamReader
Dim strLine As String
' Set prompt.
message = "Enter a directory path to open your HighScore List."
' Set title.
title = "Which HighScore List should I open?"
defaultValue = "" ' Set default value.
' Display message, title, and default value.
myValue = InputBox(message, title, defaultValue)
' If user has clicked Cancel.
If myValue Is "" Then
Exit Sub
End If
txtScores.Text = String.Empty
Try
If File.Exists(myValue) = False Then
txtScores.Text = strTxt
MessageBox.Show("Error: File/Directory Path """ & myValue & """ does not exist.")
ElseIf File.Exists(myValue) = True Then
txtScores.Text = String.Empty
If myValue.Contains("Blackjack.txt") Then
pbGame_Photo.Image = HighScores.My.Resources.Blackjack
lblGameName_Output.Text = "Blackjack"
ElseIf myValue.Contains("Mahjong.txt") Then
pbGame_Photo.Image = HighScores.My.Resources.Mahjong
lblGameName_Output.Text = "Mahjong"
ElseIf myValue.Contains("Minesweeper.txt") Then
pbGame_Photo.Image = HighScores.My.Resources.Minesweeper
lblGameName_Output.Text = "MineSweeper"
ElseIf myValue.Contains("Pinball.txt") Then
pbGame_Photo.Image = HighScores.My.Resources.Pinball
lblGameName_Output.Text = "Pinball"
ElseIf myValue.Contains("Solitaire.txt") Then
pbGame_Photo.Image = HighScores.My.Resources.Solitaire
lblGameName_Output.Text = "Solitaire"
Else
pbGame_Photo.Image = HighScores.My.Resources.Blank
lblGameName_Output.Text = "Your Game"
End If
inFile = File.OpenText(myValue)
Do While inFile.Peek <> -1
strLine = inFile.ReadLine()
Dim Res As String = ""
Dim Array(0) As Integer
For Each c As Char In strLine
If IsNumeric(c) Then
Res = Res & c
If CInt(Res) > Array(0) Then
Array(0) = CInt(Res)
End If
End If
Next
txtScores.Text = txtScores.Text & vbCrLf & strLine
lblScoreAchieved_Output.Text = Array(0)
Loop
' Close the file.
inFile.Close()
txtScores.Enabled = True
End If
Catch ex As Exception
txtScores.Text = strTxt
MessageBox.Show("Error: File/Directory Path """ & myValue & """ was found, however could not be opened." & vbCrLf & "" & vbCrLf & "Please make sure the list has a .txt file extension.")
End Try
End Sub
Private Sub frmHighScore_Editor_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' Set the focus.
gbGameInfo.Focus()
pbGame_Photo.Image = HighScores.My.Resources.Blank
' Disable text box on load since it's empty anyways.
txtScores.Enabled = False
txtScores.Text = strTxt
End Sub
Private Sub mnuFile_Save_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuFile_Save.Click
Dim outFile As StreamWriter
outFile = File.CreateText(txtScores.Text)
outFile.WriteLine(txtScores.Text)
outFile.Close()
End Sub
End Class
------FULL CODE ABOVE------
myValue = InputBox(message, title, defaultValue)
That's a very poor way to ask for a filename. Use SaveFileDialog instead. Short from the intuitive dialog that any Windows user knows how to operate, it also automatically avoids that exception.