【问题标题】:Issues with permissions when copying directories复制目录时的权限问题
【发布时间】:2014-04-12 16:11:25
【问题描述】:

我需要一些关于我的代码的帮助,我创建了一个 Visual Basic 程序,它将文件和目录从本地驱动器复制到网络共享,但我不断收到错误消息,提示访问路径 C:\Users\*username*\Documents\My Music 被拒绝。即使我在Documents 目录中没有名为My Music 的子目录。任何帮助,将不胜感激。下面是我的代码:

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

【问题讨论】:

标签: vb.net


【解决方案1】:

目录名为Music。通过一些魔术窗口将其显示为My Music。尝试使用物理名称Music

My DocumentsDocuments 存在类似的问题。

如果需要当前用户的文档目录,可以用

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

如果你想访问其他用户的目录,你需要是管理员,否则你通常没有权限访问它们!


您多次声明了相同的冗长Select Case 列表。如果你把所有的扩展都放在HashSet(Of String)中,管理起来会容易得多:

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

然后就可以测试了

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

注意:在 VB 中,集合初始化器从 VS2010 开始就存在。对于早期版本,您可以将枚举传递给构造函数:

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

更新以回应您的评论。注意:我还没有更正路径。

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

【讨论】:

  • 出于某种原因,我对需要将 Private M_mediaExtensions As New 插入代码集的确切位置有点困惑。
  • 使其成为Class Choices 的成员(在任何Sub 之外)。如果您愿意,您也可以在 Sub New 中初始化它,而不是使用集合初始化器。
  • 当我尝试将上面给出的代码放入 (myExtension) 部分时,我收到一条错误消息,指出它没有被声明。当我继续为它创建一个声明并将其设置为 m_mediaExtensions 作为哈希集时,它说它不能使用。
  • 添加了一个例子。如果需要当前用户的目录,也可以使用Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)。我还更新了原始答案。
  • 哦,好的,抱歉,谢谢您的帮助!我知道你用这个去哪里了!
猜你喜欢
  • 1970-01-01
  • 2018-01-06
  • 1970-01-01
  • 2015-05-28
  • 2010-09-24
  • 1970-01-01
  • 2011-08-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多