Pourquoi la limite de longueur de chemin d'accès de 260 caractères existe-t-elle dans Windows?

390

J'ai rencontré ce problème à quelques reprises à des moments inopportuns:

  • Essayer de travailler sur des projets Java open source avec des chemins profonds
  • Stockage d'arbres wiki Fitnesse profonds dans le contrôle de code source
  • Une erreur lors de l'utilisation de Bazaar pour importer mon arborescence de contrôle de code source

Pourquoi cette limite existe-t-elle?

Pourquoi n'a-t-il pas encore été supprimé?

Comment gérez-vous la limite de chemin? Et non, passer à Linux ou Mac OS X n'est pas une réponse valable à cette question;)

Jeffrey Cameron
la source
8
@Artelius: En fait, Windows (au moins à partir de Win2K) prend en charge les points de jonction ( en.wikipedia.org/wiki/NTFS_junction_point ), et Vista prend en charge les liens symboliques NT ( en.wikipedia.org/wiki/NTFS_symbolic_link ). Quoi qu'il en soit, alors que les liens symboliques peuvent aider à rendre les chemins plus longs / imbriqués plus conviviaux, je ne peux pas penser à quel point les liens symboliques aideraient si vous atteignez les limites de longueur de chemin.
Ashutosh Mehra
8
Même si cette limite n'existait pas, il y a toujours beaucoup d'autres limites, et chacune d'entre elles pourrait être agaçante à un moment donné. Le fait est que cette limite est si basse? Après l'ère de la 8.3, et avec du matériel de taille méga / giga, un chemin devrait maintenant être une chaîne allouée dynamiquement avec une taille pratiquement illimitée.
Roland
12
Microsoft résout enfin ce problème, dans Windows 10 Build 14352.
Warren P
3
Oui, et il semble que vous deviez modifier le manifeste de l'application pour le rendre sensible au long chemin.
Warren P
3
@PatrickSzalapski malheureusement, il a été corrigé visualstudio.uservoice.com/forums/121579-visual-studio/…
phuclv

Réponses:

231

Citant cet article https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation

Limitation de longueur de trajet maximale

Dans l'API Windows (à quelques exceptions près décrites dans les paragraphes suivants), la longueur maximale d'un chemin est MAX_PATH , qui est définie sur 260 caractères. Un chemin local est structuré dans l'ordre suivant: lettre de lecteur, deux points, barre oblique inverse, composants de nom séparés par des barres obliques inverses et un caractère nul de fin. Par exemple, le chemin d'accès maximal sur le lecteur D est "D: \ une chaîne de chemin d'accès de 256 caractères <NUL>" où "<NUL>" représente le caractère nul de fin invisible pour la page de codes système actuelle. (Les caractères <> sont utilisés ici pour plus de clarté visuelle et ne peuvent pas faire partie d'une chaîne de chemin d'accès valide.)

Nous voyons maintenant qu'il s'agit de 1 + 2 + 256 + 1 ou [lecteur] [: \] [chemin] [null] = 260. On pourrait supposer que 256 est une longueur de chaîne fixe raisonnable à partir des jours DOS. Et pour en revenir aux API DOS, nous nous rendons compte que le système a suivi le chemin actuel par lecteur, et nous avons 26 lecteurs ( 32 avec symboles) maximum (et répertoires actuels).

L'INT 0x21 AH = 0x47 dit "Cette fonction renvoie la description du chemin sans la lettre de lecteur et la barre oblique inverse initiale." Nous voyons donc que le système stocke le CWD sous forme de paire (lecteur, chemin) et vous demandez le chemin en spécifiant le lecteur (1 = A, 2 = B,…), si vous spécifiez un 0, il suppose le chemin pour le lecteur renvoyé par INT 0x21 AH = 0x15 AL = 0x19. Alors maintenant, nous savons pourquoi il est 260 et non 256, car ces 4 octets ne sont pas stockés dans la chaîne de chemin d'accès.

Pourquoi une chaîne de chemin de 256 octets, car 640 Ko est suffisant de RAM.

valli
la source
21
L'API Windows limite la longueur, même dans le dernier système d'exploitation. Microsoft a peur de casser des centaines de millions de systèmes d'exploitation utilisés aujourd'hui si cela devait changer parce qu'ils n'ont plus de génies travaillant pour eux qui comprennent l'API à l'intérieur et à l'extérieur, comme ils l'ont fait dans les années 1980 et 1990. Le risque ne vaut pas la peine de le changer. serverfault.com/questions/163419/…
MacGyver
77
@MacGyver Désolé, mais c'est un non-sens absolu. Microsoft ne veut pas casser les millions d'applications mal écrites qui supposent des choses sur le système qui n'ont jamais été garanties. Malheureusement, les choses ont été les mêmes pendant si longtemps que les développeurs en sont venus à les utiliser, donc le changer maintenant briserait les applications tierces et MS en serait responsable.
Basic
25
btw il n'y a aucune preuve que Gates ait jamais dit que le "640K Ram est suffisant pour tout le monde" computerworld.com/article/2534312
Patrick Favre
11
@Basic La limite de 260 caractères a été garantie par Windows. La constante a été déclarée comme constante , une structure a été déclarée dans les fichiers d'en-tête Windows qui ne peut contenir que 260 caractères. Il n'y a aucun moyen de le changer.
Ian Boyd
35
@Basic La constante ne change pas une fois qu'elle est compilée dans mon application. J'exécute une application qui a été construite pour la dernière fois en 1994 et qui fonctionne toujours aujourd'hui dans Windows 10. Microsoft a promis une certaine taille binaire d'un bloc de mémoire et le programmeur a suivi cette règle. Si Microsoft devait changer la constante, toutes les applications existantes, qui suivaient correctement l'API de programmation, seraient rompues . Vous ne pouvez pas casser la compatibilité binaire.
Ian Boyd
150

Ce n'est pas strictement vrai car le système de fichiers NTFS prend en charge des chemins jusqu'à 32k caractères. Vous pouvez utiliser l 'api win32 et le \\?\préfixe " " du chemin pour utiliser plus de 260 caractères.

Une explication détaillée du long chemin du blog de l'équipe .Net BCL .
Un petit extrait met en évidence le problème des longs chemins

Une autre préoccupation est le comportement incohérent qui résulterait de l'exposition de la prise en charge du long chemin. Les chemins longs avec le \\?\préfixe peuvent être utilisés dans la plupart des API Windows liées aux fichiers, mais pas dans toutes les API Windows. Par exemple, LoadLibrary, qui mappe un module à l'adresse du processus appelant, échoue si le nom de fichier est plus long que MAX_PATH. Cela signifie donc que MoveFile vous permettra de déplacer une DLL vers un emplacement tel que son chemin d'accès dépasse 260 caractères, mais lorsque vous essayez de charger la DLL, elle échouera. Il existe des exemples similaires dans les API Windows; certaines solutions de contournement existent, mais elles sont au cas par cas.

softveda
la source
4
C'est juste, mais cela signifie que vous devez utiliser P / Invoke dans de nombreux endroits et cela, à mon avis, réduit la portabilité de votre code .Net. Et si je voulais garder la compatibilité mono?
Jeffrey Cameron
1
Mon point était que vous pouvez utiliser un long chemin si vous le vouliez vraiment. Mais je conviens que c'est une douleur et personnellement j'éviterais cela aussi.
softveda
5
Ce devrait être la réponse choisie. Répond en fait à la question posée par l'utilisateur de POURQUOI cette limite existe ET fournit une solution de contournement. Vote positif pour la visibilité
KyleMit
2
Il me semble que Microsoft doit corriger ses API, et je suppose que ce n'est pas une priorité. J'ai été surpris que cette limite existe toujours dans Windows 8.
Mas
3
@Mas Le "correctif" que vous voulez a été fait depuis Windows XP. Appeler la version unicode de leur API vous permettra d'accéder au "chemin étendu". Je crois que l'explorateur gère automatiquement cela. Voici une de ces fonctions qui la prend en charge - msdn.microsoft.com/en-us/library/windows/desktop/… .
Natalie Adams
108

La question est de savoir pourquoi la limitation existe toujours. Certes, les fenêtres modernes peuvent augmenter le côté MAX_PATHpour permettre des chemins plus longs. Pourquoi la limitation n'a-t-elle pas été supprimée?

  • La raison pour laquelle il ne peut pas être supprimé est que Windows a promis qu'il ne changerait jamais.

Grâce au contrat d'API, Windows a garanti à toutes les applications que les API de fichier standard ne renverront jamais un chemin plus long que les 260caractères.

Considérez le code correct suivant:

WIN32_FIND_DATA findData;

FindFirstFile("C:\Contoso\*", ref findData);

Windows a garanti mon programme qu'il remplirait ma WIN32_FIND_DATAstructure:

WIN32_FIND_DATA {
   DWORD    dwFileAttributes;
   FILETIME ftCreationTime;
   FILETIME ftLastAccessTime;
   FILETIME ftLastWriteTime;
   //...
   TCHAR    cFileName[MAX_PATH];
   //..
}

Mon application n'a pas déclaré la valeur de la constante MAX_PATH, l'API Windows l'a fait. Mon application a utilisé cette valeur définie.

Ma structure est correctement définie et alloue uniquement des 592octets au total. Cela signifie que je ne peux recevoir qu'un nom de fichier inférieur à des 260caractères. Windows m'a promis que si j'écrivais correctement ma candidature, ma candidature continuerait de fonctionner à l'avenir.

Si Windows autorisait les noms de fichiers plus longtemps que les 260caractères, mon application existante (qui utilisait correctement l'API correcte) échouerait.

Pour quiconque appelle Microsoft à modifier la MAX_PATHconstante, il doit d'abord s'assurer qu'aucune application existante n'échoue. Par exemple, je possède toujours et j'utilise une application Windows écrite pour fonctionner sous Windows 3.11. Il fonctionne toujours sur Windows 10 64 bits. C'est ce que vous offre la compatibilité descendante.

Microsoft a créé un moyen d'utiliser les 32 768 noms de chemin complets; mais ils ont dû créer un nouveau contrat API pour le faire. D'une part, vous devez utiliser l' API Shell pour énumérer les fichiers (car tous les fichiers n'existent pas sur un disque dur ou un partage réseau).

Mais ils doivent également ne pas casser les applications utilisateur existantes. La grande majorité des applications n'utilisent pas l'API shell pour le travail sur fichier. Tout le monde appelle FindFirstFile/ FindNextFileet l'appelle un jour.

Ian Boyd
la source
4
@JosiahKeller Si c'était le cas, cela romprait le contrat initialement défini pour cette méthode, et cela pourrait écraser la mémoire involontaire et ouvrir une faille de sécurité. La seule façon de résoudre ce problème est d'offrir une nouvelle API améliorée (comme les variantes compatibles Unicode), et espérons que tout le monde recompilera / rééditera toutes ses applications en utilisant la nouvelle API.
Rowland Shaw
2
@Ryios Je ne pense pas que mes applications Windows existantes fonctionneront sur Linux.
Ian Boyd
9
La compatibilité descendante est agréable. Mais je pense qu'éviter de tels problèmes (souvent vraiment désagréables) aujourd'hui est plus important que de prendre en charge les applications Windows 3.1. Combien de personnes rencontrent des problèmes avec les longs trajets? Et combien de personnes utilisent encore des applications Windows 3.1? Ils ont même annulé la prise en charge de Windows XP. Alors pourquoi ne font-ils pas simplement une annonce, que depuis Windows [x] et les applications ultérieures qui supposent qu'il n'y aura pas de chemin de plus de 260 caractères, ne fonctionnera pas comme prévu quand ils trouveront un chemin trop long? Nos limites de vitesse ne tiennent pas compte non plus des voitures.
JuSchu
2
@JuSchu Il ne s'agit pas seulement des applications Windows 3.1. Les applications écrites aujourd'hui en utilisant la bonne API ne fonctionneront pas.
Ian Boyd
62

Depuis Windows 10. vous pouvez supprimer la limitation en modifiant une clé de registre.

Conseil À partir de Windows 10, version 1607, les limitations MAX_PATH ont été supprimées des fonctions de fichier et de répertoire Win32 courantes. Cependant, vous devez accepter le nouveau comportement.

Une clé de registre vous permet d'activer ou de désactiver le nouveau comportement de chemin long. Pour activer le comportement de chemin long, définissez la clé de registre sur HKLM\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled(Type:) REG_DWORD. La valeur de la clé sera mise en cache par le système (par processus) après le premier appel à un fichier Win32 affecté ou à une fonction de répertoire (la liste suit). La clé de registre ne sera pas rechargée pendant la durée de vie du processus. Pour que toutes les applications du système reconnaissent la valeur de la clé, un redémarrage peut être nécessaire car certains processus peuvent avoir démarré avant la définition de la clé. La clé de registre peut également être contrôlée via la stratégie de groupe à l'adresse Computer Configuration > Administrative Templates > System > Filesystem > Enable NTFS long paths. Vous pouvez également activer le nouveau comportement de chemin long par application via le manifeste:

<application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
        <ws2:longPathAware>true</ws2:longPathAware>
    </windowsSettings>
</application>
Boucle racine
la source
15
Malheureusement, même dans la dernière version Win10, l'explorateur de fichiers lui-même a toujours des problèmes avec le nom de chemin long. Même "Copier comme chemin" dans le menu contextuel ne fonctionne pas comme prévu; il ne copie que les 260 premiers caractères. Vous ne pouvez pas créer de dossier, copier / déplacer / ouvrir un fichier ... Je me demande quel est l'intérêt de ce changement.
raymai97
Notez que l'affirmation selon laquelle le paramètre système est indépendant du paramètre manifeste est incorrecte. Les deux sont obligatoires. La stratégie doit être activée au niveau du système et le manifeste doit déclarer que l'application est sensible au long chemin.
Eryk Sun
J'ai lu que cette modification pouvait entraîner des problèmes de compatibilité avec les anciennes applications 32 bits, mais ce type de problème de compatibilité est-il courant? J'aimerais faire le changement moi-même. lifehacker.com/…
KDP
32

Vous pouvez monter un dossier en tant que lecteur. À partir de la ligne de commande, si vous avez un chemin, C:\path\to\long\foldervous pouvez le mapper en lettre de lecteur en X:utilisant:

subst x: \path\to\long\folder
jonchang
la source
je reçois "Paramètre non valide j:" lors de la tentative de cette commande
barrypicker
Cette opération doit être exécutée à partir d'une invite de commande administrateur (élevée).
Mrchief
Cela échouera avec des barres obliques, doit être des barres obliques inverses.
cchamberlain
1
Je ne sais pas si cela s'applique uniquement à Windows 10, mais je viens de découvrir que lorsque j'essaie d'exécuter cette commande, si j'exécute en tant qu'administrateur comme suggéré ci-dessus, le lecteur ne semble pas être disponible. Cela est dû au fait que le comportement semble être similaire au mappage d'un lecteur réseau et qu'il est spécifique à la session, etc. exécuter la commande sans être en mode administrateur.
Jaddie
substest local-session / compte - voir superuser.com/questions/29072/… pour savoir comment le rendre «à l'échelle du système»
user2864740
18

Une façon de faire face à la limite de chemin consiste à raccourcir les entrées de chemin avec des liens symboliques.

Par exemple:

  1. créer un C:\prépertoire pour conserver des liens courts vers de longs chemins
  2. mklink /J C:\p\foo C:\Some\Crazy\Long\Path\foo
  3. ajouter C:\p\fooà votre chemin au lieu du long chemin
JDiMatteo
la source
3
N'a pas dû créer le répertoire en premier, donc l'étape 1 n'est pas nécessaire.
ohaal
2
Cette astuce ne fonctionne pas toujours car de nombreuses applications essaient de résoudre les liens
nponeccop
L' /joption crée un point de montage de jonction pour un périphérique de volume local ou un chemin sur un volume local (comme un montage de liaison Unix). Il ne crée pas de lien symbolique. C'est une distinction importante car les points de montage de jonction sont toujours évalués sur un serveur et doivent cibler les périphériques locaux, tandis que les liens symboliques sont évalués sur le client et peuvent cibler des chemins distants (si la stratégie le permet). Comme un lecteur subst.exe (c.-à-d. DefineDosDeviceW), Une cible de jonction est généralement limitée à environ 4K caractères. Il s'agit en fait de 8K caractères, répartis à peu près également entre le chemin de remplacement et le chemin d'affichage.
Eryk Sun
12

Vous pouvez activer des noms de chemin longs à l'aide de PowerShell:

Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name LongPathsEnabled -Type DWord -Value 1 

Une autre version consiste à utiliser une stratégie de groupe dans Computer Configuration/ Administrative Templates/ System/ Filesystem:

Éditeur de stratégie de groupe

MovGP0
la source
2
Chaque application doit toujours déclarer qu'elle est consciente du long chemin. Microsoft a fait un mauvais travail en communiquant cela en donnant l'impression que le manifeste d'application n'est qu'une autre façon d'activer cette fonctionnalité, plutôt que d'expliquer clairement qu'il s'agit d'un contrat entre le système d'exploitation (stratégie au niveau du système) et l'application dans lequel les deux doivent être d'accord.
Eryk Sun
8

Quant à savoir pourquoi cela existe toujours - MS ne considère pas cela comme une priorité et valorise la compatibilité ascendante par rapport à l'avancement de leur système d'exploitation (au moins dans ce cas).

Une solution de contournement que j'utilise consiste à utiliser les «noms courts» pour les répertoires du chemin, au lieu de leurs versions standard lisibles par l'homme. Donc, par exemple, pour C:\Program Files\que j'utilise, C:\PROGRA~1\ vous pouvez trouver les équivalents de noms courts en utilisant dir /x.

Conrad
la source
1
Les noms de chemin d'accès courts peuvent être désactivés dans le registre (ou était-ce le système de fichiers lui-même?), Ce n'est donc pas vraiment une solution de contournement fiable.
rubenvb
3
@rubenvb Je suis sûr que la plupart sinon toutes les fonctionnalités de Windows peuvent être désactivées dans le registre donc ¯ \ _ (ツ) _ / ¯
Conrad
La génération de noms courts peut être désactivée pour NTFS (et devrait être parce qu'elle est inefficace dans de nombreux cas), que ce soit pour l'ensemble du système ou par volume, donc c'est une approche peu fiable même pour les chemins sur le lecteur système, qui doit être NTFS. Il est possible de définir manuellement des noms courts sur des fichiers et des répertoires dans NTFS, mais cela ne s'étend pas aux systèmes de fichiers plus récents qui ne prennent pas du tout en charge les noms courts, tels que exFAT et ReFS. Les noms courts doivent être considérés comme une fonctionnalité obsolète qui est conservée pour des raisons de compatibilité dans des cas limités, comme l'ancienne API ANSI / OEM utilisant des pages de codes à un et deux octets.
Eryk Sun
@eryksun Veuillez voir mon commentaire précédent sur la désactivation des noms de chemin courts. :) Ce n'est pas parce que vous pensez qu'il doit être considéré comme obsolète qu'il l'est réellement. MS n'a pas l'intention de déprécier cette fonctionnalité. (Aussi, pourquoi installez-vous des logiciels Windows sur des partitions exFAT / ReFS?)
Conrad
Je dis toujours d'utiliser simplement des chemins de périphériques non normalisés (c'est-à-dire le préfixe "\\? \"), Car ils sont toujours disponibles et évidents. Par exemple, traduisez-le PATHet passez-le à SearchPathW. Il est également efficace, car la bibliothèque d'exécution crée de toute façon des chemins de périphérique "\\? \" Pour NT. En ce qui concerne les systèmes de fichiers plus récents, nous ne verrions probablement pas de logiciel installé sur un volume exFAT, autre que des applications portables, car il n'a aucune sécurité, mais je n'exclurais pas ReFS. Les utilisateurs installent des programmes dans des emplacements non standard pour des raisons de commodité, d'espace ou de performances.
Eryk Sun
7

Quant à savoir comment gérer la limitation de la taille du chemin sous Windows - l'utilisation de 7zip pour emballer (et décompresser) vos fichiers sensibles à la longueur du chemin semble être une solution de contournement viable. Je l'ai utilisé pour transporter plusieurs installations IDE (ces chemins de plug-in Eclipse, yikes!) Et des tas de documentation générée automatiquement et je n'ai eu aucun problème jusqu'à présent.

Je ne sais pas vraiment comment il échappe à la limite de 260 caractères définie par Windows (à partir d'un PoV technique), mais bon, cela fonctionne!

Plus de détails sur leur page SourceForge ici :

"NTFS peut réellement prendre en charge des noms de chemin pouvant aller jusqu'à 32 000 caractères."

7-zip prend également en charge ces noms longs.

Mais il est désactivé dans le code SFX. Certains utilisateurs n'aiment pas les longs chemins, car ils ne comprennent pas comment travailler avec eux. C'est pourquoi je l'ai désactivé dans le code SFX.

et notes de version :

9.32 alpha 2013-12-01

  • Prise en charge améliorée des noms de chemin de fichier de plus de 260 caractères.

4.44 beta 2007-01-20

  • 7-Zip prend désormais en charge les chemins d'accès aux fichiers de plus de 260 caractères.

REMARQUE IMPORTANTE: pour que cela fonctionne correctement, vous devrez spécifier directement le chemin de destination dans la boîte de dialogue "Extraire" de 7zip , plutôt que de glisser-déposer les fichiers dans le dossier prévu. Sinon, le dossier "Temp" sera utilisé comme cache intermédiaire et vous rebondirez dans la même limitation de 260 caractères une fois que l'Explorateur Windows commencera à déplacer les fichiers vers leur "lieu de repos final". Voir les réponses à cette question pour plus d'informations.

Priidu Neemre
la source
3
J'avais tort, 7zip et WinRAR extraient tous les dossiers et fichiers. C'est juste que la propriété d'un dossier dans Windows ne signale que le nombre de dossiers et de fichiers qui ne violent pas la limitation. C'est comme si l'Explorateur Windows ne creusait pas plus profondément pour découvrir les dossiers lorsque le chemin max était atteint.
Twisted Whisper
Il est possible de supprimer un long chemin en 7-zip avec shift-del.
Laurie Stearn
Réponse courte - utilisez 7zip pour décompresser un fichier .zip .... a fonctionné pour moi sur Windows 7
andrewcockerham
2

Une autre façon d'y faire face est d'utiliser Cygwin, selon ce que vous voulez faire avec les fichiers (c'est-à-dire si les commandes Cygwin répondent à vos besoins)

Par exemple, il permet de copier, déplacer ou renommer des fichiers que même l'explorateur Windows ne peut pas. Ou bien sûr en traiter le contenu comme md5sum, grep, gzip, etc.

Aussi pour les programmes que vous codez, vous pouvez les lier à la DLL Cygwin et cela leur permettrait d'utiliser de longs chemins (je n'ai pas testé cela cependant)

eliblanco87
la source