问题
I am using Visual Studio 2010 and coding in Visual Basic.
I have to display a progress bar while copying a directory. I have never worked with a progress bar before and not sure where to start. Here is the code I currently have.
If My.Computer.FileSystem.DirectoryExists(filePath & "IETMS\" & installFile) Then
frmWait.Show()
My.Computer.FileSystem.CopyDirectory(strFileName, filePath & "IETMS", True)
ListView1.Items.Clear()
testReload()
frmWait.Close()
Else
My.Computer.FileSystem.CreateDirectory(filePath & "IETMS\" & installFile)
frmWait.Show()
My.Computer.FileSystem.CopyDirectory(strFileName, filePath & "IETMS", True)
ListView1.Items.Clear()
testReload()
frmWait.Close()
End If
I am assuming that I need to calculate the size of the source folder and then monitor the destination folder size and set the progress bar max to the source folder size and set the value of the progress bar to the destination size, but I am not sure how to go about doing this.
回答1:
You can count the files in the source directory and then every so often count the files in the destination directory. To count the files in all subdirectories you can use a recursive sub:
Private Sub CountFiles(InFolder As String, ByRef Result As Integer)
Result += IO.Directory.GetFiles(InFolder).Count
For Each f As String In IO.Directory.GetDirectories(InFolder)
CountFiles(f, Result)
Next
End Sub
To use this do
Dim FileCount as Integer = 0
CountFiles("C:\test", FileCount)
Messagebox.Show(FileCount.ToString)
Set the progressbar to the percentage value like pbProgress.Value = CInt(DestCount/SourceCount * 100)
.
Edit: Following up on your question: You should use for example a backgroundworker, or a task, or a thread, to perform the copy and then update the progressbar in a Timer. For example you can create a sub that does the copying and then start the sub in a new task: Private WithEvents tmrUpdatePBG As Timer Private Sub StartCopy(SourceFolder As String, DestFolder As String) 'copy copy copy CopyComplete() End Sub Private Sub CopyComplete() tmrUpdatePBG.Stop() End Sub
[...]
'Whereever you start the copy process
Dim ct As New Task(Sub() StartCopy("C:\source", "C:\dest"))
ct.Start()
tmrUpdatePBG = New Timer
tmrUpdatePBG.Interval = 1000
tmrUpdatePBG.Start()
tmrUpdatePGB
would be the timer. In the tick event update the progressbar. It is started when the copying process starts and stops when the process is complete.
回答2:
I ended up counting the files in the source folder and setting the progress bar max to that number. Then inside the timer I counted the files in the destination folder and set the progress bar value to that number. Then just closed the window I created with the progress bar after the copy was finished.
I also had an issue with the progress bar (not responding) so I put the CopyDirectory inside a BackgroundWorker.
Private Sub tmrWait_Tick(sender As System.Object, e As System.EventArgs) Handles tmrWait.Tick
Dim srcFile As String = strFileName & "\" & installFile
Dim srcDir As New System.IO.DirectoryInfo(srcFile)
Dim srcFolders, srcFiles As Integer
srcFolders = srcDir.GetDirectories.GetUpperBound(0) + 1
srcFiles = srcDir.GetFiles.GetUpperBound(0) + 1
pbInstall.Maximum = srcFolders.ToString()
Dim desFile As String = filePath & "IETMS\" & installFile & "\" & installFile
Dim desDir As New System.IO.DirectoryInfo(desFile)
Dim desFolders, desFiles As Integer
desFolders = desDir.GetDirectories.GetUpperBound(0) + 1
desFiles = desDir.GetFiles.GetUpperBound(0) + 1
pbInstall.Value = desFolders.ToString()
pbInstall.Refresh()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
System.Threading.Thread.Sleep(1000)
My.Computer.FileSystem.CopyDirectory(strFileName, filePath & "IETMS\" & installFile, True)
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
frmMain.ListView1.Items.Clear()
frmMain.testReload()
Me.Close()
End Sub
Private Sub frmWait_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
BackgroundWorker1.RunWorkerAsync()
End Sub
来源:https://stackoverflow.com/questions/22303811/setting-a-progress-bar-based-on-directory-copy-in-visual-basic