Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top