IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

[C#] Comment contourner la limitation de caractères pour les chemins d'accès ?


Sujet :

C#

  1. #1
    Rédacteur
    Avatar de dev01
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 451
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 451
    Points : 6 017
    Points
    6 017
    Par défaut [C#] Comment contourner la limitation de caractères pour les chemins d'accès ?
    Bonjour.

    En écrivant un programme de backup je suis tombé sur cette limitation un peu bizarre de Windows (c'est pas moi qui le dit c'est la msdn) : Les chemins absolu ne peuvent pas faire plus de 260 caractères ... Cette limitation est très bizarre car lors de la copie, j'ai une magnifique exception PathTooLongException mais le système lui arrive à accèder à ces fichiers ...

    Le fait d'utiliser des références relatives pour le chemin ne change rien, elles sont automatiquement converties en absolue ...

    Donc si quelqu'un à une idée pour contourner cette limitation ... elle est la bienvenue.

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2003
    Messages : 835
    Points : 1 046
    Points
    1 046
    Par défaut
    Salut,

    J'ai bien peur qu'il n'y ait pas de vraie solution. Va falloir ruser et bidouiller, genre renommer certains répertoire A, B, C etc...

  3. #3
    Rédacteur
    Avatar de dev01
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 451
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 451
    Points : 6 017
    Points
    6 017
    Par défaut
    Citation Envoyé par Sphax
    Salut,

    J'ai bien peur qu'il n'y ait pas de vraie solution. Va falloir ruser et bidouiller, genre renommer certains répertoire A, B, C etc...
    Sauf que c'est absolument impensable sur un système de sauvegarde ...

  4. #4
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Points : 19 434
    Points
    19 434
    Par défaut
    Et si tu essayais de passer par les API Windows, cela ne marche pas ?

  5. #5
    Rédacteur
    Avatar de dev01
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 451
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 451
    Points : 6 017
    Points
    6 017
    Par défaut
    Citation Envoyé par Morpheus
    Et si tu essayais de passer par les API Windows, cela ne marche pas ?
    Ben tant qu'a faire du dotnet, autant eviter les api . Mais bon je vais regarder de ce coté la.

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2003
    Messages : 835
    Points : 1 046
    Points
    1 046
    Par défaut
    Trouvé ça , qui indique qu'en préfixant ton chemin par "\\?\" tu passes à une limite de 3200 caractères. A essayer...

  7. #7
    Rédacteur
    Avatar de dev01
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 451
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 451
    Points : 6 017
    Points
    6 017
    Par défaut
    Citation Envoyé par Sphax
    Trouvé ça , qui indique qu'en préfixant ton chemin par "\\?\" tu passes à une limite de 3200 caractères. A essayer...

    Ok merci, j'ai regardé.

    Alors la solution :
    Il faut utiliser l'astuce de Sphax, mais pas avec dotnet qui vous renvoi une magnifique exception ArgumentException à cause de "Caractères non conformes dans le chemin d'accès".

    Je suis donc passé par les API windows :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
     
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern bool CopyFileEx(
        string lpExistingFileName,
        string lpNewFileName,
        CopyProgressRoutine lpProgressRoutine,
        IntPtr lpData,
        ref Int32 pbCancel,
        CopyFileFlags dwCopyFlags);
     
    delegate CopyProgressResult CopyProgressRoutine(
        long TotalFileSize,
        long TotalBytesTransferred,
        long StreamSize,
        long StreamBytesTransferred,
        uint dwStreamNumber,
        CopyProgressCallbackReason dwCallbackReason,
        IntPtr hSourceFile,
        IntPtr hDestinationFile,
        IntPtr lpData);
     
    int pbCancel;
     
    enum CopyProgressResult : uint
    {
        PROGRESS_CONTINUE = 0,
        PROGRESS_CANCEL = 1,
        PROGRESS_STOP = 2,
        PROGRESS_QUIET = 3
    }
     
    enum CopyProgressCallbackReason : uint
    {
        CALLBACK_CHUNK_FINISHED = 0x00000000,
        CALLBACK_STREAM_SWITCH = 0x00000001
    }
     
    [Flags]
    enum CopyFileFlags : uint
    {
        COPY_FILE_FAIL_IF_EXISTS = 0x00000001,
        COPY_FILE_RESTARTABLE = 0x00000002,
        COPY_FILE_OPEN_SOURCE_FOR_WRITE = 0x00000004,
        COPY_FILE_ALLOW_DECRYPTED_DESTINATION = 0x00000008
    }
     
    private void XCopy(string oldFile, string newFile)
    {
        CopyFileEx(oldFile,newFile,new CopyProgressRoutine
      (this.CopyProgressHandler),IntPtr.Zero,ref pbCancel,
      CopyFileFlags.COPY_FILE_RESTARTABLE);
    }
     
    private CopyProgressResult CopyProgressHandler(
        long total,
        long transferred,
        long streamSize,
        long StreamByteTrans,
        uint dwStreamNumber,
        CopyProgressCallbackReason reason,
        IntPtr hSourceFile,
        IntPtr hDestinationFile,
        IntPtr lpData)
    {
      this.waitForm.progressBarCopyFile.Maximum = Convert.ToInt32(total);
      this.waitForm.progressBarCopyFile.Value = Convert.ToInt32(transferred);
     
      this.waitForm.labelSize.Text = streamSize.ToString();
      this.waitForm.labelTransf.Text = StreamByteTrans.ToString();
     
      Application.DoEvents();
     
      if (cancelCopy)
         return CopyProgressResult.PROGRESS_CANCEL;
      else
         return CopyProgressResult.PROGRESS_CONTINUE;
    } 
     
    [DllImport("kernel32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool CreateDirectory(
       string lpPathName,
       IntPtr lpSecurityAttributes);
    si ça interesse quelqu'un.

    Par contre attention : Les fichiers et dossiers créés malgré l'avertissement ne sont plus supprimable par l'interface graphique (énorme d'ailleurs ... )

    bref résolu mais très déçu par dotnet sur ce coup là ...

  8. #8
    Expert confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2009
    Messages
    2 030
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2009
    Messages : 2 030
    Points : 5 476
    Points
    5 476
    Par défaut
    Gros detterrage de topic, mais depuis .Net a pu évoluer!

    Est ce toujours l'unique solution?

  9. #9
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut
    C'est surtout pas du tout une limitation de .Net, mais de Windows tout court.
    Le fait est que le prefixe pour repousser la limitation n'est pas supporté par toutes les fonctions Win32, résultat, ça se ressent aussi dans .Net qui s'appuie dessus.
    C'est comme ça et c'est pas prêt de changer. Tant que Windows ne met pas à jour la totalité des API le problème restera le même. Pire, le problème restera le même tant que tous les programmes qui font des accès fichiers n'auront pas étés mis à jour.
    En effet, la limitation est une constante en C/C++ #define MAX_PATH 260.
    Donc tous les programmes qui utilisent ont été compilés en utilisant ce define, c'est à dire à peu près tous (directement ou non) ont cette limite en dur dans le binaire.
    Du coup, même si Microsoft passait ce préfixe en "par défaut", les programmes déjà compilés n'en profiteraient pas.

  10. #10
    Expert confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2009
    Messages
    2 030
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2009
    Messages : 2 030
    Points : 5 476
    Points
    5 476
    Par défaut
    Ok mais ce qui me dérange c'est que windows, dans son explorateur permet de créer des fichiers au delà de cette limite ( a peine plus mais j'arrive à 263).
    J'ai récupérer un projet dans laquelle une méthode parse récursivement un dossier.
    String[] directories = Directory.GetDirectories(chemin);
    Sauf que quand mon chemin fait plus de 260 (ici 263) de longueur, il n'est pas content .
    A l'utilisation les utilisateurs foutent leurs fichiers dans des multitudes de sous répertoires sans que windows les enguele, normal qu'ils ne comprennent pas pourquoi le logiciel oui...

    Bref le message initial datant de 2006 j'ai pensé qu'il y aurait put avoir une évolution de .Net puisque Win32 le permet. Je pense pas être le seul à avoir ce genre de soucis non?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 10
    Dernier message: 17/01/2015, 12h42
  2. Réponses: 3
    Dernier message: 06/08/2009, 17h09
  3. [TP] Comment contourner la limite de taille des variables ?
    Par celinec62 dans le forum Turbo Pascal
    Réponses: 12
    Dernier message: 20/04/2007, 21h00
  4. Réponses: 6
    Dernier message: 05/04/2006, 14h14
  5. Comment contourner l'erreur ?
    Par Le Pharaon dans le forum Langage SQL
    Réponses: 2
    Dernier message: 24/07/2005, 10h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo