none
access denied RRS feed

  • Question

  • J'asseille de créer un application qui me permet de faire mes backup automatiquement. Quand je tente d'accedder a mes images d'a partir de mes documents, on me donne un erreur "access denied". J'ai donné les droit control total a tout le monde en NTFS et j'ai toujours cette erreur. Toutefois, si j'accède a mes images directement j'ai pas ce problème. Voici mon code qui marche pas:

    Note: Les lignes en commentaires sont des trucs que j'ai asseillé pour remédier au problème.

    Public Class main

     

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

     

            '------------------------------------------ Initialisation --------------------------------------------

            Dim fileDestination As String = System.AppDomain.CurrentDomain.BaseDirectory().First() + ":\Backup"

            Dim user As String = System.Environment.UserName

            If System.IO.Directory.Exists(fileDestination) Then

                If System.IO.Directory.Exists(fileDestination + "\" + user) Then

     

     

     

                Else

                    System.IO.Directory.CreateDirectory(fileDestination + "\" + user)

                End If

            Else

                System.IO.Directory.CreateDirectory(fileDestination)

                System.IO.Directory.CreateDirectory(fileDestination + "\" + user)

            End If

     

            fileDestination = fileDestination + "\" + user

     

            '----------------------------------------- Copie de donnes -------------------------------------------

     

            Dim mydoc As String = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)

            copyfromroot(mydoc, fileDestination)

        End Sub

     

        Public Sub copyfromroot(ByVal fileSource As String, ByVal fileDestination As String)

            Dim listdir As New List(Of String)

            Dim souslist As New List(Of String)

            Dim count As Integer = 0

            listdir.Add(fileSource)

            '--->> Remplie la liste de sousdossier

            While listdir.Distinct.Count() > count

                count = listdir.Distinct.Count()

                souslist.Clear()

                For Each s In listdir.Distinct

                    souslist.Add(s)

                Next

                'For Each s In souslist

                ' Dim attrib As FileAttribute = FileAttribute.ReadOnly = False

                ' System.IO.File.SetAttributes(s, attrib)

                'Next

                For Each dossier In souslist

                    'System.IO.File.GetAccessControl(dossier)

                    For Each dos In System.IO.Directory.GetDirectories(dossier)

                        listdir.Add(dos)

                    Next

                Next

            End While

            '--->> Copie les fichiers de la liste

            For Each s In listdir.Distinct

                souslist.Add(s)

            Next

            For Each dire In souslist

                Dim s As String = dire

                Dim d As String = fileDestination

                Dim user As String = System.Environment.UserName

                Dim nom As String

                Dim index As Integer

                index = dire.IndexOf(user) + user.Length

                nom = dire.Substring(index)

                d = d + nom

                copyalldirectories(s, d)

                copyallfiles(s, d)

            Next

        End Sub

     

        Public Function countdirectories(ByVal s As String)

            Dim r As Integer

            For Each d In System.IO.Directory.GetFiles(s)

                r += 1

            Next

            Return r

        End Function

     

        Public Function countfiles(ByVal s As String)

            Dim r As Integer

            For Each f In System.IO.Directory.GetFiles(s)

                r += 1

            Next

            Return r

        End Function

     

        Public Sub copyallfiles(ByVal s As String, ByVal d As String)

            If System.IO.Directory.Exists(d) Then

            Else

                System.IO.Directory.CreateDirectory(d)

            End If

            If countfiles(s) > 0 Then

                For Each f In System.IO.Directory.GetFiles(s)

                    Dim nom As String

                    Dim index As Integer

                    Dim fileDestinationSub As String

                    index = f.LastIndexOf("\") + 1

                    nom = f.Substring(index)

                    fileDestinationSub = d + "\" + nom

                    If System.IO.File.Exists(fileDestinationSub) Then

                        Dim source As Date = System.IO.File.GetLastWriteTime(f)

                        Dim destin As Date = System.IO.File.GetLastWriteTime(fileDestinationSub)

                        Dim backup As String = d + "\z" + nom

                        If source > destin Then

                            System.IO.File.Replace(f, fileDestinationSub, backup)

                            System.IO.File.Copy(fileDestinationSub, f)

                        End If

                    Else

                        System.IO.File.Copy(f, fileDestinationSub)

                    End If

                Next

            End If

        End Sub

     

        Public Sub copyalldirectories(ByVal s As String, ByVal d As String)

            If countdirectories(s) > 0 Then

                For Each dos In System.IO.Directory.GetDirectories(s)

                    Dim nom As String

                    Dim index As Integer

                    Dim fileDestinationSub As String

                    index = dos.LastIndexOf("\") + 1

                    nom = dos.Substring(index)

                    fileDestinationSub = d + "\" + nom

                    If System.IO.Directory.Exists(fileDestinationSub) Then

                    Else

                        System.IO.Directory.CreateDirectory(fileDestinationSub)

                    End If

                Next

            End If

        End Sub

    End Class

     

    vendredi 9 juillet 2010 18:54

Réponses

  • Bonjour,

    J'ai pris le temps (c'est le 14 juillet... :-)) d'exécuter votre code et j'ai le même problème que M. PETRESCU.
    En fait, l'erreur "Access Denied" se produit lorsque vous accédez à un lien dur (hardlink).

    Par exemple : C:\Users\Gilles.Tourreau\Documents\Ma Musique fait référence vers C:\Users\Gilles\Music.

    Ces liens ont été introduits depuis Vista afin de garder des chemins compatibles avec les applications développées pour Windows XP. (Il en existe plein d'autres).

    Vous devez donc ignorer ces liens durant votre copie. Pour cela utilisez la méthode File.GetAttributes() comme ceci :

    If (File.GetAttributes("C:\Users\Gilles\Documents\Ma Musique") And FileAttributes.ReparsePoint) = FileAttributes.ReparsePoint Then
      ' Ce fichier/répertoire est un lien dur il faut donc l'ignorer !
    End If
    

    Au passage, au lieu de parcourir répertoire par répertoire, pourquoi ne pas faire appel directement à :

    Directory.GetFiles("C:\Users\Gilles.Tourreau\", "*.*", SearchOption.AllDirectories)
    

    Qui vous permet de récupérer dans un tableau de String(), tous les fichiers contenu dans un répertoire (et de manière récursive).

    Cordialement


    Gilles TOURREAU - MVP C# - MCTS Windows Forms - Architecte .NET/Consultant/Formateur - http://gilles.tourreau.fr
    • Marqué comme réponse Gary-William mercredi 14 juillet 2010 22:30
    mercredi 14 juillet 2010 09:52
    Modérateur

Toutes les réponses

  • Bonjour,

    La création du répertoire propage-t-elle les droits ?

    Cordialement


    Gilles TOURREAU - MVP C# - MCTS Windows Forms - Architecte .NET/Consultant/Formateur - http://gilles.tourreau.fr
    samedi 10 juillet 2010 07:39
    Modérateur
  • Tu as dans le code que j'ai donné la totalité de mon programme. Je sais pas ce que tu veux dire par " propage-t-elle les droits", mais je doute que je l'ai fait. Peut être que si tu me donne une exemple ou que tu me l'explique autrement je comprendrais mieux...

    lundi 12 juillet 2010 20:46
  • Bonjour,

     

    Je crois que votre problème vient du l’utilisation de Environment.SpecialFolder.MyDocuments.

     

    Cette énumération retourne C:\users\<nom_utilisateur>\Documents, l’équivalent du répertoire Personnel, à partir de la documentation MSDN.

    En reproduisant votre exemple, j’ai eu une exception pour le chemin C:\users\<nom_utilisateur>\Documents\My Music, qui n’existe pas. Toutefois, l’application le trouve comme sous-répertoire de c:\users\<nom_utilisateur>\Documents, dans la partie de code

    listdir.Add(fileSource)

            '--->> Remplie la liste de sousdossier

            While listdir.Distinct.Count() > count

                count = listdir.Distinct.Count()

                souslist.Clear()

                For Each s In listdir.Distinct

                    souslist.Add(s)

                Next

     

    Essayez d’analyser la méthode ‘copyfromroot’ et la modalité utilisée pour récupérer les chemins, car l’erreur se trouve sans doute la bas.

     

    Cordialement,

    Alex

    ________________

    Publiez un article sur une de ces technologies : Visual Basic, C#, C++, .NET, ASP.NET, SQL Server, Silverlight, SharePoint 2010, SharePoint 2007

    Astuces pour Visual Studio 2010

    Didacticiels et astuces : VB.NET, C#, ASP.NET, .NET Framework, Silverlight, Workflow Foundation, WPF

    Café des usages

    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

     

     

     

    mardi 13 juillet 2010 10:10
  • Merci, ta réponse est très pertinante. Je crois avoir trouvé une alternative à mon problème. Mydocument et ses sous documents a pour propriétaire SYSTEM. Si je change le propriétaire pour l'utilisateur connecté, le programme fonctionne bien. Toutefois, je cherche encore comment changer le propriétaire de mydocuments et ses sousdossier directement via le programme afin d'éviter d'avoir à le faire manuellement. Si vous avez une suggestion, moi je m'aprette à ajouter un System.IO.Directory.GetAccessControl(mydoc).SetOwner(account) dans mon "for each" qui va chercher tous mes fichiers sources.

    Si vous connaissez une solution plus efficace cela me ferait vraiment plaisir. De toute façon, avec la veine que j'ai, je doute que sa va fonctionner.

    mardi 13 juillet 2010 17:53
  • Bonjour,

    J'ai pris le temps (c'est le 14 juillet... :-)) d'exécuter votre code et j'ai le même problème que M. PETRESCU.
    En fait, l'erreur "Access Denied" se produit lorsque vous accédez à un lien dur (hardlink).

    Par exemple : C:\Users\Gilles.Tourreau\Documents\Ma Musique fait référence vers C:\Users\Gilles\Music.

    Ces liens ont été introduits depuis Vista afin de garder des chemins compatibles avec les applications développées pour Windows XP. (Il en existe plein d'autres).

    Vous devez donc ignorer ces liens durant votre copie. Pour cela utilisez la méthode File.GetAttributes() comme ceci :

    If (File.GetAttributes("C:\Users\Gilles\Documents\Ma Musique") And FileAttributes.ReparsePoint) = FileAttributes.ReparsePoint Then
      ' Ce fichier/répertoire est un lien dur il faut donc l'ignorer !
    End If
    

    Au passage, au lieu de parcourir répertoire par répertoire, pourquoi ne pas faire appel directement à :

    Directory.GetFiles("C:\Users\Gilles.Tourreau\", "*.*", SearchOption.AllDirectories)
    

    Qui vous permet de récupérer dans un tableau de String(), tous les fichiers contenu dans un répertoire (et de manière récursive).

    Cordialement


    Gilles TOURREAU - MVP C# - MCTS Windows Forms - Architecte .NET/Consultant/Formateur - http://gilles.tourreau.fr
    • Marqué comme réponse Gary-William mercredi 14 juillet 2010 22:30
    mercredi 14 juillet 2010 09:52
    Modérateur
  • Merci, sa fonctionne et double merci pour le conseil, sa me sauve 30 lignes de code...
    mercredi 14 juillet 2010 22:32