bckelley
bckelley

Reputation: 69

Copy directories and files with ProgressBar

Trying to create a console application to copy directories from the source to the destination and either the progress bar does nothing while files are copied...

My.Computer.FileSystem.CopyDirectory(source, destination)

For i = 1 To 100
    Console.Write(String.Format("Copy progress: {0}%" & vbCr, i))
    Threading.Thread.Sleep(100)
Next

or the ProgressBar says "Copy Progress 1%" the entire time it's copying...

For i = 1 To 100
    Console.Write(String.Format("Copy progress: {0}%" & vbCr, i))
    My.Computer.FileSystem.CopyDirectory(source, destination)
    Threading.Thread.Sleep(100)
Next

Wondering what I am doing wrong because I am obviously putting the My.Computer line in the wrong spot!

Upvotes: 1

Views: 2017

Answers (2)

Jimi
Jimi

Reputation: 32248

A simple solution, using Linq Select to copy the file list returned by DirectoryInfo.GetFiles()

Pass the sample method an array of Source Directories and a Destination Directory.
The progress (0-100%) is printed to the Output window, and a ProgressBar gives a visual feedback of the copy status for each Source Path.

This method will return the list of all files copied.

enter image description here

Dim sourcePath As String() = New String() {"[SourcePath1]", "[SourcePath2]", "[SourcePath3]"}
Dim destinationPath As String = "[DestinationPath]"
Dim filesCopied As List(Of String) = CopyDirectoryWithProgress(sourcePath, destinationPath)
Console.ReadLine()

Private Function CopyDirectoryWithProgress(sourcePath As String(), destPath As String) As List(Of String)

    Dim allFilesCopied As List(Of String) = New List(Of String)
    Dim progressBarPassSymbol As Char = ChrW(&H25A0)
    Dim progressBarEmptySymbol As String = New String(ChrW(&H2014), 30)

    For Each sPath As String In sourcePath
        Dim fileInfo As New DirectoryInfo(sPath).GetFiles()
        Dim numberOfFiles As Integer = fileInfo.Length - 1
        Dim progressBarPass As Double = (30 / numberOfFiles)
        Dim increment As Double = 100 / numberOfFiles
        Directory.CreateDirectory(destPath)

        Console.CursorLeft = 0
        Console.Write("Copy progress: ")
        Console.CursorLeft = 20
        Console.Write(progressBarEmptySymbol)

        allFilesCopied.AddRange(fileInfo.
            Select(Function(f, i)
               File.Copy(Path.Combine(sPath, f.Name), Path.Combine(destPath, f.Name), True)
               Console.CursorLeft = 15
               Console.Write("{0:g}% " &
                   New String(progressBarPassSymbol, CInt((i + 1) * progressBarPass)),
                   CInt((i + 1) * increment))

               Return f.FullName
           End Function))
        Console.WriteLine()
    Next
    Return allFilesCopied
End Function

For an interesting method to perform this task with a much faster file enumerator, see this CodeProject article: A Faster Directory Enumerator

Upvotes: 2

user8142888
user8142888

Reputation:

You can invoke the Windows built-in progress bar when copying using the UIOption.AllDialogs:

My.Computer.FileSystem.CopyFile("C:\text.txt", "C:\my_folder\text.txt", FileIO.UIOption.AllDialogs, FileIO.UICancelOption.DoNothing)

Upvotes: 1

Related Questions