Results 1 to 4 of 4

Thread: copy multiple files + folders with progress

  1. #1

    Thread Starter
    Addicted Member Lectere's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    222

    Post copy multiple files + folders with progress

    I've been searching on this forum for this, and with partial succes.

    I'm busy on a explorer.exe clone witch supports drag and drop of files ect. I want to handle the copy,move, detele operations in a seperate thread(background worker) with a progress dialog using file.copy.

    All is working file, except one thing:
    -when coping 300 files of 5 MB's, I can calculate MB/s, remaining time etc.
    -when coping one file op 3 GB's, I can't calculate speed and progress

    I've found you can also use: My.Computer.FileSystem.CopyDirectory( sourcePath, destinationPath, UIOption.AllDialogs) which uses a build in progress dialog.

    Using My.Computer.FileSystem.CopyDirectory( sourcePath, destinationPath, UIOption.AllDialogs), you can only specify ONE file or ONE directory. This is a problem because you won't get an update on the total progress, which can be a operation of several files and several sub folders.

    So the question can you somehow use: My.Computer.FileSystem.CopyDirectory using multiple files/folders.

  2. #2
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: copy multiple files + folders with progress

    You can use Shell32 functionality to copy multiple files:-
    vbnet Code:
    1. Imports System.Runtime.InteropServices
    2. Imports System.IO
    3. Imports System.Text
    4.  
    5. Friend Class Win32API
    6.     <Flags()> _
    7.     Public Enum FILEOP_FLAGS As UShort
    8.         FOF_MULTIDESTFILES = &H1
    9.         FOF_CONFIRMMOUSE = &H2
    10.         ''' <summary>
    11.         ''' Don't create progress/report
    12.         ''' </summary>
    13.         FOF_SILENT = &H4
    14.         FOF_RENAMEONCOLLISION = &H8
    15.         ''' <summary>
    16.         ''' Don't prompt the user.
    17.         ''' </summary>
    18.         FOF_NOCONFIRMATION = &H10
    19.         ''' <summary>
    20.         ''' Fill in SHFILEOPSTRUCT.hNameMappings.
    21.         ''' Must be freed using SHFreeNameMappings
    22.         ''' </summary>
    23.         FOF_WANTMAPPINGHANDLE = &H20
    24.         FOF_ALLOWUNDO = &H40
    25.         ''' <summary>
    26.         ''' On *.*, do only files
    27.         ''' </summary>
    28.         FOF_FILESONLY = &H80
    29.         ''' <summary>
    30.         ''' Don't show names of files
    31.         ''' </summary>
    32.         FOF_SIMPLEPROGRESS = &H100
    33.         ''' <summary>
    34.         ''' Don't confirm making any needed dirs
    35.         ''' </summary>
    36.         FOF_NOCONFIRMMKDIR = &H200
    37.         ''' <summary>
    38.         ''' Don't put up error UI
    39.         ''' </summary>
    40.         FOF_NOERRORUI = &H400
    41.         ''' <summary>
    42.         ''' Dont copy NT file Security Attributes
    43.         ''' </summary>
    44.         FOF_NOCOPYSECURITYATTRIBS = &H800
    45.         ''' <summary>
    46.         ''' Don't recurse into directories.
    47.         ''' </summary>
    48.         FOF_NORECURSION = &H1000
    49.         ''' <summary>
    50.         ''' Don't operate on connected elements.
    51.         ''' </summary>
    52.         FOF_NO_CONNECTED_ELEMENTS = &H2000
    53.         ''' <summary>
    54.         ''' During delete operation,
    55.         ''' warn if nuking instead of recycling (partially overrides FOF_NOCONFIRMATION)
    56.         ''' </summary>
    57.         FOF_WANTNUKEWARNING = &H4000
    58.         ''' <summary>
    59.         ''' Treat reparse points as objects, not containers
    60.         ''' </summary>
    61.         FOF_NORECURSEREPARSE = &H8000
    62.     End Enum
    63.  
    64.     <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
    65.     Public Structure SHFILEOPSTRUCT
    66.         Public hwnd As IntPtr
    67.         <MarshalAs(UnmanagedType.U4)> Public wFunc As FileFuncFlags
    68.         <MarshalAs(UnmanagedType.LPWStr)> Public pFrom As String
    69.         <MarshalAs(UnmanagedType.LPWStr)> Public pTo As String
    70.         <MarshalAs(UnmanagedType.U2)> Public fFlags As FILEOP_FLAGS
    71.         <MarshalAs(UnmanagedType.Bool)> Public fAnyOperationsAborted As Boolean
    72.         Public hNameMappings As IntPtr
    73.         <MarshalAs(UnmanagedType.LPWStr)> Public lpszProgressTitle As String '  only used if FOF_SIMPLEPROGRESS
    74.     End Structure
    75.  
    76.     <Flags()> _
    77.     Public Enum FileFuncFlags As UInteger
    78.         FO_MOVE = &H1
    79.         FO_COPY = &H2
    80.         FO_DELETE = &H3
    81.         FO_RENAME = &H4
    82.     End Enum
    83.  
    84.     <DllImport("shell32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> _
    85.     Public Shared Function SHFileOperation(<MarshalAs(UnmanagedType.Struct)> ByRef lpFileOp As SHFILEOPSTRUCT) As Integer
    86.     End Function
    87. End Class
    88.  
    89. Public Class ShellFileOperations
    90.  
    91.     Public Shared Function MoveFiles(ByVal files As IList(Of String), ByVal destinationPath As String) As Boolean
    92.         If CheckAllFilesExist(files) Then
    93.             Return CopyOrMoveFilesAndFolders(files, destinationPath, True)
    94.         Else
    95.             Throw New FileNotFoundException("One of the source files doesn't exist")
    96.         End If
    97.  
    98.     End Function
    99.     Public Shared Function MoveFolders(ByVal folders As IList(Of String), ByVal destinationPath As String) As Boolean
    100.  
    101.         If CheckAllFoldersExist(folders) Then
    102.             Return CopyOrMoveFilesAndFolders(folders, destinationPath, True)
    103.         Else
    104.             Throw New FileNotFoundException("One of the source files doesn't exist")
    105.         End If
    106.     End Function
    107.  
    108.     Public Shared Function CopyFiles(ByVal files As IList(Of String), ByVal destinationPath As String) As Boolean
    109.  
    110.         If CheckAllFilesExist(files) Then
    111.             Return CopyOrMoveFilesAndFolders(files, destinationPath, False)
    112.         Else
    113.             Throw New FileNotFoundException("One of the source files doesn't exist")
    114.         End If
    115.     End Function
    116.  
    117.     Public Shared Function CopyFolders(ByVal folders As IList(Of String), ByVal destinationPath As String) As Boolean
    118.  
    119.         If CheckAllFoldersExist(folders) Then
    120.             Return CopyOrMoveFilesAndFolders(folders, destinationPath, False)
    121.         Else
    122.             Throw New FileNotFoundException("One of the source files doesn't exist")
    123.         End If
    124.     End Function
    125.  
    126.     Private Shared Function CopyOrMoveFilesAndFolders(ByVal filesOrFolders As IList(Of String), ByVal destinationPath As String, ByVal move As Boolean) As Boolean
    127.  
    128.         Dim shOP As Win32API.SHFILEOPSTRUCT
    129.  
    130.         shOP.fFlags = Win32API.FILEOP_FLAGS.FOF_MULTIDESTFILES
    131.         shOP.hNameMappings = IntPtr.Zero
    132.         shOP.hwnd = IntPtr.Zero
    133.         shOP.lpszProgressTitle = ""
    134.  
    135.         If move Then
    136.             shOP.wFunc = Win32API.FileFuncFlags.FO_MOVE
    137.         Else
    138.             shOP.wFunc = Win32API.FileFuncFlags.FO_COPY
    139.         End If
    140.  
    141.         shOP.pFrom = MakeShellList(filesOrFolders)
    142.         shOP.pTo = MakeShellList(MakeDestFileList(filesOrFolders, destinationPath))
    143.  
    144.         'Function returns zero on success
    145.         Return Not CBool(Win32API.SHFileOperation(shOP))
    146.  
    147.     End Function
    148.  
    149.     Private Shared Function MakeDestFileName(ByVal sourceFullPath As String, ByVal destPath As String)
    150.         Dim fileNameOnly As String = Path.GetFileName(sourceFullPath)
    151.  
    152.         Return destPath + "\" + fileNameOnly
    153.     End Function
    154.  
    155.     Private Shared Function MakeDestFileList(ByVal files As IList(Of String), ByVal destPath As String) As String()
    156.         Dim ret As New List(Of String)
    157.  
    158.         For Each f As String In files
    159.             ret.Add(MakeDestFileName(f, destPath))
    160.         Next
    161.         Return ret.ToArray
    162.     End Function
    163.  
    164.     Private Shared Function MakeShellList(ByVal strings As IList(Of String)) As String
    165.  
    166.         Dim sb As New StringBuilder
    167.  
    168.         For Each Strn As String In strings
    169.             sb.Append(Strn)
    170.             sb.Append(ChrW(0))
    171.         Next
    172.  
    173.         sb.Append(ChrW(0))
    174.  
    175.         Return sb.ToString
    176.     End Function
    177.  
    178.     Private Shared Function CheckAllFilesExist(ByVal files As IList(Of String)) As Boolean
    179.  
    180.         For Each File As String In files
    181.             If IO.File.Exists(File) = False Then
    182.                 Return False
    183.             End If
    184.         Next
    185.         Return True
    186.     End Function
    187.  
    188.     Private Shared Function CheckAllFoldersExist(ByVal folders As IList(Of String)) As Boolean
    189.  
    190.         For Each folder As String In folders
    191.             If IO.Directory.Exists(folder) = False Then
    192.                 Return False
    193.             End If
    194.         Next
    195.         Return True
    196.     End Function
    197.  
    198. End Class
    Put the above into a code file in your project and you can use it like this:-
    vbnet Code:
    1. Dim b = ShellFileOperations.CopyFiles(New String() {"c:\file1.dat", "C:\file2.dat"}, "c:\destFolder")

    The above shows how to copy two files, file1.dat and file2.dat to a folder called destFolder.

    Please note that CopyFiles and the other similar functions take an IList(Of String) so that means you can pass an array, list or collection of files to them.
    Last edited by Niya; Mar 5th, 2013 at 04:03 AM.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  3. #3

    Thread Starter
    Addicted Member Lectere's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    222

    Re: copy multiple files + folders with progress

    Hey Niya,

    Thanks for thinking along, when i search for your solution on MSDN its says the newer function is: IFileOperation, but there is no wrapper for VB which allows you to copy muliple files.

    This custom wrapper does, but its not in vb.net (its in c#). So i'm gonna translate that for vb.net!

    But thanks a lot for thinking along. Are you interested in the translated wrapper when I'm finish with it?

  4. #4
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: copy multiple files + folders with progress

    Sure, I'd love to see it.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width