2 Replies - 7752 Views - Last Post: 19 November 2008 - 11:18 PM Rate Topic: -----

#1 fenrisulfr  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 31
  • Joined: 16-August 08

Copying directory and progressbars

Posted 19 November 2008 - 07:00 PM

is there any way to show a progressbar in teh applicationa nd not in a seperate dialog box ?

 My.Computer.FileSystem.CopyDirectory(sourcedir, savedir, showUI:=FileIO.UIOption.AllDialogs)


this shows the windows copy box thing but i just want a single progessbar in the application.

is there any way to do that?
Is This A Good Question/Topic? 0
  • +

Replies To: Copying directory and progressbars

#2 magicmonkey  Icon User is offline

  • D.I.C Regular

Reputation: 106
  • View blog
  • Posts: 484
  • Joined: 12-September 08

Re: Copying directory and progressbars

Posted 19 November 2008 - 10:44 PM

Well IO.Directory nor IO.DirectoryInfo does not have a CopyTo method like IO.File\IO.FileInfo does. So I decided to extend the IO.DirectoryInfo to add it for you and included the option to add a delegate to be notified of the progress. This is a new feature in .NET 3.5 called Extension Methods. It is how alot of LINQ is implemented.

Below is an example of using the IO.DirectoryInfo.CopyTo extended method...
Public Class Form1
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim d As New IO.DirectoryInfo(Application.StartupPath)
        d.CopyTo(Application.StartupPath & "\..\CopyDirectoryTest", AddressOf HandleDirectoryCopyTo)
    End Sub

    Private Sub HandleDirectoryCopyTo(ByVal sender As Object, ByVal e As DirectoryCopyToEventArgs)
        Debug.WriteLine(e.Description)
    End Sub
End Class



This is the Module which contains the CopyTo extended method I wrote. Add a new module to your project and paste it in.
Module DirectoryInfoExtensions
    Public Delegate Sub DirectoryCopyToDelegate(ByVal sender As Object, ByVal e As DirectoryCopyToEventArgs)

    <System.Runtime.CompilerServices.Extension()> _
   Public Sub CopyTo(ByVal aDirectoryInfo As IO.DirectoryInfo, ByVal Destination As String)
        Dim DestinationDirectory As New IO.DirectoryInfo(Destination)
        Dim Count As Integer = 0
        CopyTo(aDirectoryInfo, aDirectoryInfo, DestinationDirectory, Count, CountFiles(aDirectoryInfo), Nothing)
    End Sub

    <System.Runtime.CompilerServices.Extension()> _
    Public Sub CopyTo(ByVal aDirectoryInfo As IO.DirectoryInfo, ByVal Destination As String, ByVal Handler As DirectoryCopyToDelegate)
        Dim DestinationDirectory As New IO.DirectoryInfo(Destination)
        Dim Count As Integer = 0
        CopyTo(aDirectoryInfo, aDirectoryInfo, DestinationDirectory, Count, CountFiles(aDirectoryInfo), Handler)
    End Sub

    Private Sub CopyTo(ByVal aDirectoryInfo As IO.DirectoryInfo, ByVal SourceDirectory As IO.DirectoryInfo, ByVal DestinationDirectory As IO.DirectoryInfo, ByRef Count As Integer, ByVal Total As Integer, ByVal Handler As DirectoryCopyToDelegate)
        'Create Destination Directory
        DestinationDirectory.Create()

        'Copy Directories
        For Each SelectDirectory As IO.DirectoryInfo In SourceDirectory.GetDirectories
            CopyTo(aDirectoryInfo, SelectDirectory, New IO.DirectoryInfo(IO.Path.Combine(DestinationDirectory.FullName, SelectDirectory.Name)), Count, Total, Handler)
        Next

        'Copy Files
        For Each SelectFile As IO.FileInfo In SourceDirectory.GetFiles
            SelectFile.CopyTo(IO.Path.Combine(DestinationDirectory.FullName, SelectFile.Name), True)
            Count += 1
            If Handler IsNot Nothing Then
                Handler.Invoke(aDirectoryInfo, New DirectoryCopyToEventArgs With {.Count = Count, .Total = Total, .CurrentFile = SelectFile})
            End If
        Next
    End Sub

    Private Function CountFiles(ByVal SourceDirectory As IO.DirectoryInfo) As Integer
        Dim TotalFiles As Integer

        'Count Directories
        For Each SelectDirectory As IO.DirectoryInfo In SourceDirectory.GetDirectories
            TotalFiles += CountFiles(SelectDirectory)
        Next

        'Count Files
        TotalFiles += SourceDirectory.GetFiles.Count

        Return TotalFiles
    End Function

    Public Class DirectoryCopyToEventArgs
        Inherits EventArgs

        Private _CurrentFile As IO.FileInfo
        Public Property CurrentFile() As IO.FileInfo
            Get
                Return _CurrentFile
            End Get
            Set(ByVal value As IO.FileInfo)
                _CurrentFile = value
            End Set
        End Property

        Private _Count As Integer
        Public Property Count() As Integer
            Get
                Return _Count
            End Get
            Set(ByVal value As Integer)
                _Count = value
            End Set
        End Property

        Private _Total As Integer
        Public Property Total() As Integer
            Get
                Return _Total
            End Get
            Set(ByVal value As Integer)
                _Total = value
            End Set
        End Property

        Public ReadOnly Property Progress() As Double
            Get
                Return Total \ Count
            End Get
        End Property

        Public ReadOnly Property Description() As String
            Get
                Return String.Format("{0} of {1} files copied.", Count, Total)
            End Get
        End Property
    End Class
End Module



It could use some cleaning up, but seems to work fine on the few tests I performed. If it is a bit too techy for you, you can look at the code and see how I have used the IO.Directory and IO.File static methods to copy the files over to a new directory.
Was This Post Helpful? 0
  • +
  • -

#3 PsychoCoder  Icon User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1639
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Re: Copying directory and progressbars

Posted 19 November 2008 - 11:18 PM

In order to do something like tht, the most straight forward way to accomplish that is to use a Delegate since you cannot access/modify a GUI control from outside the thread that initially created it, so you have to marshal the call onto the GUI's thread. Here is some code that shows the basic premise of accomplishing something like this.

On the form you need a ProgressBar Control and two TextBox controls that hold the original directory and new directory names.

NOTE: This VB.NET version has not been tested as of yet, it is to show the general concept

Namespace DefaultNamespace
	''' <summary>
	''' Description of Class1.
	''' </summary>
	Public Class Class1
		Private Delegate Sub ProgressDelegate(ByVal totalSize As Integer, ByVal totalSoFar As Integer)
		Private Delegate Sub CalculateProgressDelegate(ByVal dir As String)
		Public Sub New()
		End Sub

		''' <summary>
		''' method for updating the progress bar asynchronously
		''' </summary>
		''' <param name="totalSize">total size of the upload</param>
		''' <param name="totalSoFar">size of the current file</param>
		''' <param name="file">the file we're currently working on</param>
		Private Sub ShowProgress(ByVal totalSize As Integer, ByVal totalSoFar As Integer, ByVal file As String)
			'this is used to make sure we're on the right thread
			If rtbStatus.InvokeRequired = False Then
				'update the progress bar
				progressBar1.Maximum = totalSize
				'increment progress bar by size of current file
				progressBar1.Increment(totalSoFar)
				Dim percent As Integer = CInt(((CDbl(progressBar1.Value) / CDbl(progressBar1.Maximum)) * 100))
				progressBar1.CreateGraphics().DrawString(percent.ToString() + "%", New Font("Arial", CSng(8.25), FontStyle.Bold), Brushes.Black, New PointF(progressBar1.Width / 2 - 10, progressBar1.Height / 2 - 7))

				If totalSoFar = totalSize Then
					progressBar1.Value = progressBar1.Maximum
				End If
			Else
				' Show progress asynchronously
				Dim showProgress As New ProgressDelegate(ShowProgress)
				BeginInvoke(showProgress, New Object() {totalSize, totalSoFar, file})
			End If
		End Sub


		''' <summary>
		''' method for processing the current file:
		''' Here we get the files size, the files directory and name to pass to our
		''' upload method which calls our web service. This is also where
		''' we update the progress bar
		''' </summary>
		''' <param name="file">the file to be processed</param>
		Public Sub ProcessFile(ByVal file As String, ByVal newDir As String)
			'get a new FileInfo instance so we can retrieve info for this file
			Dim original As New FileInfo(file)
			Dim copy As New FileInfo(file.Replace(original.Directory, newDir))

			'update the progres bar
			ShowProgress(Convert.ToInt32(uploadSize), Convert.ToInt32(soFar), b.ToString())

			'now copy the file to it's new location
			File.Copy(original.FullName, copy.FullName, True)

			'update progess
			ShowProgress(Convert.ToInt32(uploadSize), Convert.ToInt32(soFar), b.ToString())
		End Sub

		''' <summary>
		''' method that loops through all the files in the directory
		''' and it's sub directories (recursion) and passes it to
		''' the <see cref="ProcessFile"/>
		''' </summary>
		''' <param name="dir"></param>
		Public Sub CopyFiles(ByVal originalDir As String, ByVal newDir As String)
			'get a string array of all the files in the directory
			Dim files As String() = Directory.GetFiles(originalDir)
			'loop through each file passing it to the ProcessFile method
			For Each file As String In files
				ProcessFile(file, newDir)
			Next

			'get all the directories within the directory provided
			Dim [sub] As String() = Directory.GetDirectories(originalDir)
			'loop through each directory calling Upload recursively to
			'get all those files to the ProcessFile method so they can be
			'uploaded
			For Each d As String In [sub]
				CopyFile(d)
			Next
		End Sub

		Private Sub cmdCopy_Click(ByVal sender As Object, ByVal e As EventArgs)

			' Asynch delegate method
			Dim calcProgress As New CalculateProgressDelegate(CopyFiles)
			calcProgress.BeginInvoke(txtNewDirectory.Text, Nothing, Nothing)

		End Sub
	End Class
End Namespace




Hope that helps :)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1