0

I tried to be as descriptive in my title as possible, but to clarify I have a VB.Net application and I'm attempting to copy a directory to another machine with file permissions and all child files/folders.

Using "My.Computer.FileSystem.CopyDirectory", the directory that is chosen to be copied does NOT get copied over like the MSDN implies; but instead the contents of the directory are copied to the destination directory. If there is a folder inside of that directory, the folder is copied but the permissions of said folder are NOT. Both of these things pose a huge issue because it's imperative that the original folder's permissions, and any other folders inside of the original folder, get copied along with it. This is possible using PowerShell, is it possible using VB.Net?

Thanks in advance.

For Each item As String In stations
            copyTo = stations([i].ToString)

            If IsHostAvailable(copyTo) Then
                LogBreak()
                LogOutput(TimeStamp() + ": " + copyTo + " available. Beginning file push...")
                copyTo = "\\"
                copyTo = Path.Combine(copyTo, stations([i].ToString))
                copyToLoc1 = copyTo.ToString
                copyToLoc1 = Path.Combine(copyTo, pushLocationBox1.ToString.Remove(0, 36))

                LogBreak()
                LogOutput(TimeStamp() + ": " + "Coyping- " + "\n" + pushFrom1 + "\n" + "...to station '" + copyTo + "'.")

                If (File.Exists(pushFrom1) AndAlso (System.IO.Directory.Exists(copyToLoc1))) Then
                    Dim pushFileName As String = Path.GetFileName(pushFrom1)
                    My.Computer.FileSystem.CopyFile(pushFrom1, Path.Combine(copyToLoc1, pushFileName), True)
                    LogOutput(TimeStamp() + ": " + "File 1 copied.")
                ElseIf (File.Exists(pushFrom1) AndAlso (System.IO.Directory.Exists(copyToLoc1) = False)) Then
                    Directory.CreateDirectory(copyToLoc1)
                    LogOutput(TimeStamp() + ": " + "Directory created.")
                    My.Computer.FileSystem.CopyFile(pushFrom1, copyToLoc1, True)
                    LogOutput(TimeStamp() + ": " + "File 1 copied.")
                ElseIf (Directory.Exists(pushFrom1)) Then
                    My.Computer.FileSystem.CopyDirectory(pushFrom1, copyToLoc1, True)
                    Dim srcPerms As New FileInfo(pushFrom1)
                    Dim destPerms As New FileInfo(Path.Combine(copyToLoc1, pushFrom1))
                    Dim permissions As FileSecurity = srcPerms.GetAccessControl()
                    permissions.SetAccessRuleProtection(True, True)
                    destPerms.SetAccessControl(permissions)
                    LogOutput(TimeStamp() + ": " + "Directory 1 copied.")
                Else
                    LogOutput(TimeStamp() + ": " + "The file or directory selected to be copied can no longer be found. (#1)")
                    MsgBox("The file or directory selected to be copied can no longer be found. (#1)", MsgBoxStyle.Critical, "Error!")
                End If
            Else
                LogOutput(TimeStamp() + ": " + "Ping request timed out on " + copyTo + ". Moving to next station...")
                FailOutput(copyTo)
            End If
            i += 1
        Next
Brady
  • 403
  • 1
  • 8
  • 19
  • 2
    Permissions never get copied over from the last time I remember, and rightly so due to possible different FS (File System) on the destination folder. you may need to take an extra step and copy over the security permissions and apply them if needs be. Please also post relevant code for the first question - without this, we cannot see what you are doing wrong. – Ahmed ilyas Mar 25 '15 at 22:37
  • Interesting. Added a snippit of the copy function I'm using. I first check to see if the selected object to copy is a file or folder... It's too bad about the permissions. PowerShell's "Copy-Item" has absolutely no qualms about copying over the permissions of the directory, and it doesn't care if it's a file or directory either! Why would MS allow something like that in one language but not another? – Brady Mar 25 '15 at 22:42
  • 2
    Powershell is not a language.... and it is a different functionality than code writing...Powershell is an admin type tool which serves as a different purpose than manual coding. Going back to the original question, simply doing this will work: https://msdn.microsoft.com/en-us/library/bb762914(v=vs.110).aspx – Ahmed ilyas Mar 25 '15 at 22:43
  • If there's no way to do this using VB.Net, is there a discreet way I can add a PowerShell script into the program? I'm guessing not since in order to execute PS scripts you have to set your execution policy first... – Brady Mar 25 '15 at 22:44
  • yes there is. http://blogs.msdn.com/b/zainnab/archive/2008/07/26/calling-a-powershell-script-from-your-net-code.aspx or https://code.msdn.microsoft.com/windowsdesktop/VBPowerShell-6b4f83ea – Ahmed ilyas Mar 25 '15 at 22:46
  • 1
    Copy-Item is not an operator or a language construct, it is a cmdlet, that is, a program. When you ask the OS to do the copy, it does not copy permissions. What happens when you move is more interesting ([Moving a file does not recalculate inherited permissions](http://blogs.msdn.com/b/oldnewthing/archive/2006/08/24/717181.aspx), [Wait, so does moving a file recalculate inherited permissions or doesn't it?](http://blogs.msdn.com/b/oldnewthing/archive/2013/09/24/10451467.aspx)). If you don't like this default behaviour, you can copy permissions yourself. – GSerg Mar 25 '15 at 22:46
  • Thanks guys. So then is it not possible to copy over the permissions the way I have my code set up now? – Brady Mar 25 '15 at 22:48
  • possible duplicate of [Copy a file with its original permissions](http://stackoverflow.com/questions/9163831/copy-a-file-with-its-original-permissions) – GSerg Mar 25 '15 at 22:48
  • correct - it is NOT. – Ahmed ilyas Mar 25 '15 at 22:48
  • Somehow the solution @GSerg Linked to stripped the file of its permissions (such as system and the original creator) but re-added the permissions that were added manually... That's a first step I guess. I edited my initial post with my code thus far. – Brady Mar 25 '15 at 23:21
  • Ok, so I realized I was using FileSecurity rather than DirectorySecurity. Now the only thing left to figure out is why "My.Computer.FileSystem.CopyDirectory" is not copying the directory that was selected, but the contents of said directory. Is there a way around this? – Brady Mar 25 '15 at 23:36
  • As it stands it's copying the *contents* and permissions of the folder selected rather than copying the entire selected folder over along with its permissions. – Brady Mar 25 '15 at 23:47
  • @Ahmedilyas Actually, using the code I have above, I added just 4 additional lines of code using the Security.AccessControl class that GSerg linked to and was easily able to copy the permission from the source directory to the destination directory without changing any other part of my code. – Brady Mar 27 '15 at 19:11
  • correct however your question was why it does not copy it over when doing a move/copy.... you also need to have the correct permissions in order to copy those permissions over or add permissions – Ahmed ilyas Mar 27 '15 at 19:30

1 Answers1

1

i think the directory path in copyToLoc1 is not correct, i tested code below and it works.

My.Computer.FileSystem.CopyDirectory("E:\Users\test1\Desktop\test", "E:\Users\test1\Desktop\test2", True)

Your program might not be storing info to copyToLoc1 correctly to debug and see if its the case

comment out this code

'My.Computer.FileSystem.CopyDirectory(pushFrom1, copyToLoc1, True)

add the following code

MsgBox(copyToLoc1)

You would get a msg with the new directory you trying to create.

see if its the correct directory you are trying to create.

user4335407
  • 352
  • 1
  • 3
  • 11