1

I need some help wit my code, I've created a Visual Basic program that copies files and directories from the local drive to a network share, but I keep getting an error saying that access to path C:\Users\*username*\Documents\My Music is denied. Even though I don't have a sub-directory called My Music in the Documents directory. Any help would be appreciated. Here is my code below:

Imports System.IO

Public Class Choices
    Private Sub Choices_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    End Sub

    Public Sub btnDocuments_Click(sender As Object, e As EventArgs) Handles btnDocuments.Click
        Dim docsDirectory, destdocsDirectory, userDirectory, userName, hDrive, mydocsDirectory, destmydocsDirectory As String
        'Function to pull user profile path
        hDrive = Environment.GetEnvironmentVariable("homedrive")
        userName = Environment.GetEnvironmentVariable("username")
        userDirectory = Environment.GetEnvironmentVariable("userprofile")
        docsDirectory = userDirectory + "\Documents"
        destdocsDirectory = hDrive + userName + "\My Files"
        mydocsDirectory = "C:\My Documents"
        destmydocsDirectory = hDrive + userName + "\My Documents"

        'Used for error checking
        'MessageBox.Show(sourceDirectory + vbCrLf + destDirectory)

        If (My.Computer.FileSystem.DirectoryExists(destdocsDirectory)) Then
            For Each foundFile As String In My.Computer.FileSystem.GetFiles(docsDirectory, _
                    FileIO.SearchOption.SearchAllSubDirectories, "*.*")
                Select Case LCase(Path.GetExtension(foundFile))
                    Case ".mks"
                    Case ".wav"
                    Case ".jpg"
                    Case ".wmv"
                    Case ".lnk"
                    Case ".png"
                    Case ".exe"
                    Case ".jpeg"
                    Case ".dll"
                    Case ".msi"
                    Case ".bmp"
                    Case ".url"
                    Case ".log"
                    Case ".dat"
                    Case ".ini"
                    Case ".propdesc"
                    Case ".arx"
                    Case ".hdi"
                    Case ".mc3"
                    Case ".css"
                    Case ".gif"
                    Case ".tif"
                    Case ".tiff"
                    Case ".htm"
                    Case ".chm"
                    Case ".pc3"
                    Case ".mp3"
                    Case ".mp4"
                    Case Else
                        My.Computer.FileSystem.CopyFile(foundFile, destdocsDirectory & "\" & Path.GetFileName(foundFile), showUI:=FileIO.UIOption.AllDialogs)
                End Select
            Next
        Else
            My.Computer.FileSystem.CreateDirectory(destdocsDirectory)
            For Each foundFile As String In My.Computer.FileSystem.GetFiles(docsDirectory, _
                    FileIO.SearchOption.SearchAllSubDirectories, "*.*")
                Select Case LCase(Path.GetExtension(foundFile))
                    Case ".mks"
                    Case ".wav"
                    Case ".jpg"
                    Case ".wmv"
                    Case ".lnk"
                    Case ".png"
                    Case ".exe"
                    Case ".jpeg"
                    Case ".dll"
                    Case ".msi"
                    Case ".bmp"
                    Case ".url"
                    Case ".log"
                    Case ".dat"
                    Case ".ini"
                    Case ".propdesc"
                    Case ".arx"
                    Case ".hdi"
                    Case ".mc3"
                    Case ".css"
                    Case ".gif"
                    Case ".tif"
                    Case ".tiff"
                    Case ".htm"
                    Case ".chm"
                    Case ".pc3"
                    Case ".mp3"
                    Case ".mp4"
                    Case Else
                        My.Computer.FileSystem.CopyFile(foundFile, destdocsDirectory & "\" & Path.GetFileName(foundFile), showUI:=FileIO.UIOption.AllDialogs)
                End Select
            Next
        End If

        If (My.Computer.FileSystem.DirectoryExists(mydocsDirectory)) Then
            For Each foundFile As String In My.Computer.FileSystem.GetFiles(mydocsDirectory, _
                    FileIO.SearchOption.SearchAllSubDirectories, "*.*")
                Select Case LCase(Path.GetExtension(foundFile))
                    Case ".mks"
                    Case ".wav"
                    Case ".jpg"
                    Case ".wmv"
                    Case ".lnk"
                    Case ".png"
                    Case ".exe"
                    Case ".jpeg"
                    Case ".dll"
                    Case ".msi"
                    Case ".bmp"
                    Case ".url"
                    Case ".log"
                    Case ".dat"
                    Case ".ini"
                    Case ".propdesc"
                    Case ".arx"
                    Case ".hdi"
                    Case ".mc3"
                    Case ".css"
                    Case ".gif"
                    Case ".tif"
                    Case ".tiff"
                    Case ".htm"
                    Case ".chm"
                    Case ".pc3"
                    Case "."
                    Case Else
                        My.Computer.FileSystem.CopyFile(foundFile, destmydocsDirectory & "\" & Path.GetFileName(foundFile), showUI:=FileIO.UIOption.AllDialogs)
                End Select
            Next
        Else
            MessageBox.Show(mydocsDirectory + "Does not exist")
        End If
    End Sub

    Private Sub btnDesktop_Click(sender As Object, e As EventArgs) Handles btnDesktop.Click
        Dim deskDirectory, destdeskDirectory, userDirectory, userName, hDrive As String
        hDrive = Environment.GetEnvironmentVariable("homedrive")
        userName = Environment.GetEnvironmentVariable("username")
        userDirectory = Environment.GetEnvironmentVariable("userprofile")
        deskDirectory = userDirectory + "\Desktop"
        destdeskDirectory = hDrive + userName + "\Desktop"
        If (My.Computer.FileSystem.DirectoryExists(deskDirectory)) Then
            For Each foundFile As String In My.Computer.FileSystem.GetFiles(deskDirectory, _
                    FileIO.SearchOption.SearchAllSubDirectories, "*.*")
                Select Case LCase(Path.GetExtension(foundFile))
                    Case ".mks"
                    Case ".wav"
                    Case ".jpg"
                    Case ".wmv"
                    Case ".lnk"
                    Case ".png"
                    Case ".exe"
                    Case ".jpeg"
                    Case ".dll"
                    Case ".msi"
                    Case ".bmp"
                    Case ".url"
                    Case ".log"
                    Case ".dat"
                    Case ".ini"
                    Case ".propdesc"
                    Case ".arx"
                    Case ".hdi"
                    Case ".mc3"
                    Case ".css"
                    Case ".gif"
                    Case ".tif"
                    Case ".tiff"
                    Case ".htm"
                    Case ".chm"
                    Case ".pc3"
                    Case "."
                    Case Else
                        My.Computer.FileSystem.CopyDirectory(foundFile, destdeskDirectory & "\" & Path.GetFileName(foundFile), showUI:=FileIO.UIOption.AllDialogs)
                End Select
            Next
        End If
    End Sub
End Class
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
jfritts6524
  • 77
  • 2
  • 11
  • You could switch your usage of directories with http://msdn.microsoft.com/en-us/library/14tx8hby%28v=vs.110%29.aspx – SomeNickName Apr 12 '14 at 19:45

1 Answers1

1

The directory is called Music. By some magic windows displays it as My Music. Try to use the physical name Music.

The analogous problematic exists for My Documents and Documents.

If you need the documents directory of the current user, you can get it with

destmydocsDirectory =  Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)

If you want to access the directories of other users, you need to be an administrator, otherwise you won't usually have the rights to access them!


You declared the same lengthy Select Case list several times. It would be much easier to manage if you put all the extensions in a HashSet(Of String):

Private m_mediaExtensions As New HashSet(Of String)() From { ".mks", ".wav",  ... }

Then you can test

If m_mediaExtensions.Contains(myExtension) Then
    ...
Else
    ...
End If

Note: In VB the collection initializers exist since VS2010. For earlier versions you can pass an enumeration to the constructor:

m_mediaExtensions = New HashSet(Of String)(New String() {".mks", ".wav", ...})

UPDATE in reponse to your comment. Note: I have not corrected the paths yet.

Imports System.IO

Public Class Choices
    Private m_mediaExtensions As HashSet(Of String) = _
       New HashSet(Of String)(New String() {".mks", ".wav", ".jpg"})

    Public Sub btnDocuments_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnDocuments.Click
        Dim docsDirectory, destdocsDirectory, userDirectory, userName, hDrive, mydocsDirectory, destmydocsDirectory As String
        'Function to pull user profile path
        hDrive = Environment.GetEnvironmentVariable("homedrive")
        userName = Environment.GetEnvironmentVariable("username")
        userDirectory = Environment.GetEnvironmentVariable("userprofile")
        docsDirectory = userDirectory + "\Documents"
        destdocsDirectory = hDrive + userName + "\My Files"
        mydocsDirectory = "C:\My Documents"
        destmydocsDirectory = hDrive + userName + "\My Documents"

        'Used for error checking
        'MessageBox.Show(sourceDirectory + vbCrLf + destDirectory)

        If Not Directory.Exists(destdocsDirectory) Then
            My.Computer.FileSystem.CreateDirectory(destdocsDirectory)
        End If
        For Each foundFile As String In My.Computer.FileSystem.GetFiles(docsDirectory, _
          FileIO.SearchOption.SearchAllSubDirectories, "*.*")
            If Not m_mediaExtensions.Contains(LCase(Path.GetExtension(foundFile))) Then
                My.Computer.FileSystem.CopyFile(foundFile, destdocsDirectory & "\" & Path.GetFileName(foundFile), showUI:=FileIO.UIOption.AllDialogs)
            End If
        Next

        If Directory.Exists(mydocsDirectory) Then
            For Each foundFile As String In My.Computer.FileSystem.GetFiles(mydocsDirectory, _
              FileIO.SearchOption.SearchAllSubDirectories, "*.*")
                If Not m_mediaExtensions.Contains(LCase(Path.GetExtension(foundFile))) Then
                    My.Computer.FileSystem.CopyFile(foundFile, destmydocsDirectory & "\" & Path.GetFileName(foundFile), showUI:=FileIO.UIOption.AllDialogs)
                End If
            Next
        Else
            MessageBox.Show(mydocsDirectory + "Does not exist")
        End If
    End Sub

    Private Sub btnDesktop_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnDesktop.Click
        Dim deskDirectory, destdeskDirectory, userDirectory, userName, hDrive As String
        hDrive = Environment.GetEnvironmentVariable("homedrive")
        userName = Environment.GetEnvironmentVariable("username")
        userDirectory = Environment.GetEnvironmentVariable("userprofile")
        deskDirectory = userDirectory + "\Desktop"
        destdeskDirectory = hDrive + userName + "\Desktop"
        If Directory.Exists(deskDirectory) Then
            For Each foundFile As String In My.Computer.FileSystem.GetFiles(deskDirectory, _
              FileIO.SearchOption.SearchAllSubDirectories, "*.*")
                If Not m_mediaExtensions.Contains(LCase(Path.GetExtension(foundFile))) Then
                    My.Computer.FileSystem.CopyDirectory(foundFile, destdeskDirectory & "\" & Path.GetFileName(foundFile), showUI:=FileIO.UIOption.AllDialogs)
                End If
            Next
        End If
    End Sub
End Class
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • For some reason I'm a bit confused on where exactly I need to insert the Private M_mediaExtensions As New, set of code. – jfritts6524 Apr 14 '14 at 12:56
  • Make it a member of `Class Choices` (outside of any `Sub`). You can then initialize it in `Sub New` as well, instead of using the collection initializer, if you prefer. – Olivier Jacot-Descombes Apr 14 '14 at 12:59
  • When I try putting in that code you gave above in the (myExtension) portion i get an error saying it's not declared. And when I go ahead and create a declaration for it and set it to m_mediaExtensions as a hashset it says that it cant be used. – jfritts6524 Apr 14 '14 at 14:04
  • Added an example. If you need the directories of the current user, you can also use `Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)`. I also updated the original answer. – Olivier Jacot-Descombes Apr 14 '14 at 14:43
  • Ohhhh ok sorry thanks for the help! I see where you went with this! – jfritts6524 Apr 14 '14 at 14:45
  • See also the simplifications I made to your routines. – Olivier Jacot-Descombes Apr 14 '14 at 14:47
  • I just tried the corrections you made and it's still giving me the same error saying that access to My Music is denied. – jfritts6524 Apr 14 '14 at 14:49
  • The function call `Environment.GetFolderPath(Environment.SpecialFolder.MyMusic)` returns `"C:\Users\Oli\Music"` on my system. But if you are trying to read the music folder of another user, you might well get an access denied message, unless you have administrator rights. – Olivier Jacot-Descombes Apr 14 '14 at 14:58
  • I'm not trying to copy the root of the user folder i.e C:\User\username\ I'm just trying to copy C:\User\username\Documents and then the Desktop folder using a different button click. – jfritts6524 Apr 14 '14 at 16:10
  • Are you trying to read the folders of the current user (of yourself)? In this case, I would not read the environment variables but use `Environment.GetFolderPath` as shown above. It returns you the full path of the documents, the music and the desktop. – Olivier Jacot-Descombes Apr 14 '14 at 16:33
  • If you look when I set the variable for example: deskDirectory i used the other variable userDirectory and used the Environment.GetEnvironmentVariable("userprofile") in the userDirectory varaible. Which what that does is it get the users C:\Users\username\ directory and then i threw on a + "\Documents" so it would pull the full path, C:\Users\username\Documents. So this program can be used by any user. So this application should load up the forms, and then should find in the sub for the button click it should get their home drive which is a networked location, and then it will grab their user_ – jfritts6524 Apr 14 '14 at 17:23
  • username then their userDirectory and then it will find the deskDirectory which would be C:\Users\username\Desktop and the same thing to the C:\Users\username\Documents. The reason I've programmed it this way is so that no matter who is logged in it will work. Because these files are being copied out to a network share to a location for example: H:\username and then I'm creating a sub directory for example H:\username\Documents or H:\username\Desktop – jfritts6524 Apr 14 '14 at 17:27
  • So to get these environment variable I went to the command line and typed set and then used the variable to create the environment variable – jfritts6524 Apr 14 '14 at 17:30
  • I've even tried making the change in the userDirectory variable of changing it to: userDirectory = Einvironment.GetFolderPath(Environment.SpecialFolder.UserProfile) and it still didn't work still throws up an error saying that access is denied. – jfritts6524 Apr 14 '14 at 17:43
  • I even tried changing the docsDirectory Variable to: docsDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) Still same error – jfritts6524 Apr 14 '14 at 17:45
  • When running the code I get `destdocsDirectory = "C:Oli\My Files"` and `destmydocsDirectory = "C:Oli\My Documents"`. Both are wrong, since the backslash (`\`) after `C:` is missing. This SO question treats the same question: http://stackoverflow.com/q/10477113/880990 – Olivier Jacot-Descombes Apr 14 '14 at 20:04
  • First the link you gave is for C# not VB.net, and on top the reason you're getting that is the home drive on my machine is the H: drive not the C: the C: drive is the local drive H: is a networked share drive. So in theory the coding and the stuff you're getting is technically right but it doesn't work right on your machine because the home drive variable is not the same on your machine. – jfritts6524 Apr 14 '14 at 20:17
  • I know that it is a C# link; however the problematic is exacly the same. It's not VB or C# specific problem. This `My Music` directory is a symbolic link. You will need to find a way to avoid these symbolic links. – Olivier Jacot-Descombes Apr 14 '14 at 20:19
  • Sorry I wasn't understanding what you were trying to say. How do I handle that issue? Is there a way that I could write an extra bit of code that basically says when we hit that unhandled exception to just continue the code? – jfritts6524 Apr 15 '14 at 13:57
  • Enclose the code that throws an exception in a [`Try Catch`](http://msdn.microsoft.com/en-us/library/fk6t46tz.aspx) statement. – Olivier Jacot-Descombes Apr 15 '14 at 18:03