0
votes

As in the Title, i want to have a progressbar, which is showing the process while copying.

My code so far:

Imports System.IO Imports Scripting

Public Class Form1 Dim Source, Destination As String Dim fso As FileSystemObject = New FileSystemObject Dim SourceSize As Double

Private Sub ResetThings()
    ProgressBar1.Value = 0

End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim xFilesCount = Directory.GetFiles(Source).Length
    Dim xFilesTransferred As Integer = 0

    For Each xFiles In Directory.GetFiles(Source)
        My.Computer.FileSystem.CopyDirectory(Source, Destination, True)
        xFilesTransferred += 1
        ProgressBar1.Value = xFilesTransferred * 100 / xFilesCount
        ProgressBar1.Update()
    Next
End Sub

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

End Sub

Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs)

End Sub

Private Sub TextBox2_TextChanged(sender As Object, e As EventArgs)

End Sub

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    FolderBrowserDialog1.ShowDialog()
    Source = FolderBrowserDialog1.SelectedPath
    first.Text = "Original: " & Source
    ResetThings()
End Sub

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    FolderBrowserDialog1.ShowDialog()
    Destination = FolderBrowserDialog1.SelectedPath
    Dim Temp = Source
    Do
        Temp = Temp.Substring(1)
    Loop Until Temp.Contains("\") = False
    Destination = Destination
    Second.Text = "Ziel: " & Destination

End Sub
2
What are you having trouble on? - Cal-cium
The progressbar isnt showing anything. But the files are copying... - bigMre
I would suggest by looking at it, that you need to set the ProgressBar1.Maximum. and then you can use this line ProgressBar1.Increment(1) to make it go up by one after every file. and because you have set a maximum, once all files are done the progress bar should be complete - Cal-cium
Okay thanks.. but how do i use ProgressBar1.Maximum and ProgressBar1.Increment(1) with my code? First time with progressbars :) - bigMre
Problem is that you don't copy files, but entire directory - this is single command and doesn't refresh anything. - Arvo

2 Answers

0
votes

Your main problem is that My.Computer.FileSystem.CopyDirectory(Source, Destination, True) is a synchronous call which blocks the UI and prohibits any interaction as long as you copy all contents of the source directory to the target directory.

You need to:

  1. break down the Copy process to copy single files rather then the whole directory
  2. make the Copy process async to keep the UI responsive and allow the ProgrressBar to be updated.

For the first goal use File.Copy(soruceFile, destinationFile) in a loop for each file in a directory, like:

For Each xFileWithPath In Directory.GetFiles(Source)
     Dim xFile As String = Path.GetFileName(xFileWithPath)
     Try
         File.Copy(xFileWithPath, Path.Combine(Destination, xFile))
         //...
     Catch ex As Exception
          //something went wrong
      End Try
 Next

For the second one use a BackgroundWorker and set the required properties + event handler:

 Dim bw As New BackgroundWorker()
 bw.WorkerReportsProgress = True
 AddHandler bw.DoWork, AddressOf copyFiles
 AddHandler bw.ProgressChanged, AddressOf updateUI

DoWork is the task the BackgroundWorker executes. ProgressChanged is the event raised which you want to subscribe to update your ProgressBar.

updateUI could look like:

Private Sub updateUI(sender As Object, e As ProgressChangedEventArgs)
        ProgressBar1.Value = e.ProgressPercentage
        ProgressBar1.Update()
End Sub

copyFiles combines the copy part + progress update part:

 Private Sub copyFiles(sender As Object, e As DoWorkEventArgs)
        Dim xFilesCount = Directory.GetFiles(Source).Length
        For Each xFileWithPath In Directory.GetFiles(Source)
            Dim xFile As String = Path.GetFileName(xFileWithPath)
            Try
                File.Copy(xFileWithPath, Path.Combine(Destination, xFile))
                xFilesTransferred += 1
                bw.ReportProgress(xFilesTransferred * 100 / xFilesCount)
            Catch ex As Exception
                 //Something went wrong
            End Try
        Next
    End Sub

Eventually you have to start the BackgroundWorker in your button click event:

 bw.RunWorkerAsync()

Edit: If you want to copy all files of all sub-directories include SearchOption.AllDirectories as last parameter to Directory.GetFiles

-1
votes

Due to new information in the comment thread, I've updated my answer.

I've tested this and it worked on my computer. I've changed it now so that you read in the total amount of files in your directory as the maximum and now you are looping through each file in your source directory and copying over the files and keeping track and the progressbar updates.

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim xFilesCount = Directory.GetFiles(source).Length
    Dim xFilesTransferred As Integer = 0

    ProgressBar1.Maximum = xFilesCount

    For Each xFiles In Directory.GetFiles(source)
        Dim fileinfo As FileInfo = New FileInfo(xFiles)
        System.IO.File.Copy(xFiles, Path.Combine(Destination, fileinfo.Name), True)
        xFilesTransferred += 1
        ProgressBar1.Increment(1)
        ProgressBar1.Refresh()
    Next
End Sub

If you want do more directories you can loop through directories using recursion or by looping through. I assume you are creating a back up program, this link might be useful: Using Recursion To Create A Program To Backup Folders