web-dev-qa-db-fra.com

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

Je me suis heurté à ce problème à quelques reprises à des moments inopportuns:

  • essayer de travailler sur des projets open source Java avec des chemins d'accès profonds
  • Stocker des arbres wiki Fitnesse profonds dans le contrôle de source
  • Une erreur en essayant d'utiliser Bazaar pour importer mon arbre de contrôle de 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, le passage à Linux ou Mac OS X n'est pas une réponse valable à cette question;)

369
Jeffrey Cameron

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

Limite maximale de longueur de chemin

Dans l'API Windows (à quelques exceptions près décrites dans les paragraphes suivants), la longueur maximale d'un chemin est MAX_PATH , définie à 260 caractères. Un chemin local est structuré dans l'ordre suivant: lettre de lecteur, deux points, barre oblique inverse, nom des composants séparés par des barres obliques inverses et un caractère nul de fin. Par exemple, le chemin maximal sur le lecteur D est "D: \une chaîne de chemin de 256 caractères<NUL> "où" <NUL> "représente le caractère nul de fin invisible pour la page de code système actuelle (les caractères <> sont utilisés ici pour des raisons 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 peut supposer que 256 est une longueur de chaîne fixe raisonnable à partir des jours DOS. Et en revenant aux API DOS, nous réalisons que le système a suivi le chemin actuel par lecteur, et nous avons 26 (maximum) lecteurs (et les répertoires actuels).

INT 0x21 AH = 0x47 indique "Cette fonction renvoie la description du chemin sans la lettre du 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, le chemin du lecteur renvoyé par INT 0x21 AH = 0x15 AL = 0x19. Nous savons donc maintenant pourquoi il s'agit de 260 et non de 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 640K est assez de RAM.

214
valli

Ce n'est pas strictement vrai car le système de fichiers NTFS prend en charge les chemins d'accès allant jusqu'à 32 000 caractères. Vous pouvez utiliser les API win32 et "\\?\" pour préfixer le chemin d'accès afin d'utiliser plus de 260 caractères.

Une explication détaillée du long chemin du .Net blog de l'équipe 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 la mise à disposition d'un support à long chemin. Les longs chemins avec le préfixe \\?\ peuvent être utilisés dans la plupart des API Windows associées aux fichiers, mais pas dans toutes les API Windows. Par exemple, LoadLibrary, qui mappe un module dans l'adresse du processus appelant, échoue si le nom du fichier est supérieur à 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 si 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.

142
softveda

La question est pourquoi la limitation existe-t-elle encore. Sûrement Windows moderne peut augmenter le côté de MAX_PATH pour 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 que cela ne changerait jamais.

Par le biais du contrat d’API, Windows a garanti à toutes les applications que les API de fichier standard ne renverraient jamais un chemin plus long que 260 caractères.

Considérez le code correct suivant:

WIN32_FIND_DATA findData;

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

Windows garanti mon programme pour qu'il peuplera ma structure WIN32_FIND_DATA:

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, contrairement à l'API Windows. Mon application a utilisé cette valeur définie.

Ma structure est correctement définie et n'alloue que 592 octets au total. Cela signifie que je ne peux recevoir qu'un nom de fichier inférieur à 260 caractères. Windows promis moi que si j'écrivais correctement mon application, mon application continuerait à fonctionner dans le futur.

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

Toute personne appelant Microsoft à modifier la constante MAX_PATH doit d'abord vérifier qu'aucune application existante n'échoue. Par exemple, je possède et utilise toujours une application Windows écrite pour fonctionner sous Windows 3.11. Il fonctionne toujours sous Windows 10 64 bits. C'est ce que vous garantit la compatibilité avec les versions antérieures.

Microsoft did crée un moyen d'utiliser les 32 768 noms de chemin d'accès complets; mais ils ont dû créer un nouveau contrat d'API pour le faire. D'une part, vous devez utiliser Shell API 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 not utilisent l'API Shell pour le traitement de fichiers. Tout le monde appelle simplement FindFirstFile/FindNextFile et l'appelle un jour.

101
Ian Boyd

À partir de Windows 10., vous pouvez supprimer la limitation en modifiant une clé de registre.

Conseil À partir de Windows 10, version 1607, les limitations de 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 d'accès long. Pour activer le comportement de chemin d'accès 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 est la suivante). La clé de registre ne sera pas rechargée pendant la durée 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 d'accès 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>
55
Root Loop

Vous pouvez monter un dossier en tant que lecteur. À partir de la ligne de commande, si vous avez un chemin C:\path\to\long\folder, vous pouvez le mapper sur la lettre de lecteur X: à l'aide de:

subst x: \path\to\long\folder
29
jonchang

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

Par exemple:

  1. créer un répertoire C:\p pour conserver les liens courts vers les chemins longs
  2. mklink /J C:\p\foo C:\Some\Crazy\Long\Path\foo
  3. ajoutez C:\p\foo à votre chemin au lieu du long chemin
16
JDiMatteo

Pour faire face à la limitation de la taille du chemin d'accès sous Windows, utilisez 7Zip pour compresser (et décompresser) vos fichiers sensibles à la longueur du chemin d'accès, ce qui semble être une solution de contournement viable. Je l'ai utilisé pour transporter plusieurs installations IDE (ces chemins d'accès au plug-in Eclipse, beurk!) Et des piles de documentation générée automatiquement, et je n'ai pas rencontré de problème jusqu'à présent.

Vous ne savez pas vraiment comment il échappe à la limite de 260 caractères définie par Windows (à partir d'un PoV technique), mais bon, ça marche!

Plus de détails sur leur page SourceForge ici :

"NTFS peut prendre en charge les noms de chemin d'accès d'une longueur maximale de 32 000 caractères."

7-Zip supporte aussi ces noms longs.

Mais c'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 d'accès aux fichiers 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 devez spécifier le chemin de destination dans la boîte de dialogue 7Zip "Extraire". directement, plutôt que de glisser-déposer les fichiers dans le dossier prévu. Sinon, le dossier "Temp" sera utilisé en tant que cache provisoire et vous suivrez la même limitation de 260 caractères une fois que l'Explorateur Windows commencera à déplacer les fichiers vers leur "dernier emplacement". Voir les réponses à cette question pour plus d'informations.

7
Priidu Neemre

En ce qui concerne pourquoi cela existe toujours - MS ne le considère pas comme une priorité et valorise la compatibilité avec les versions antérieures par rapport à la progression de leur système d'exploitation (du moins dans ce cas).

Une solution de contournement que j'utilise consiste à utiliser les "noms abrégés" pour les répertoires dans le chemin, au lieu de leurs versions standard lisibles par l'homme. Donc par exemple pour C:\Program Files\ je voudrais utiliser C:\PROGRA~1\ Vous pouvez trouver les équivalents des noms abrégés en utilisant dir /x.

7
Conrad

Vous pouvez activer les 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:

Group Policy Editor

6
MovGP0

C'est une valeur par défaut pour une raison quelconque, mais vous pouvez facilement la remplacer par cette clé de registre:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem]
"LongPathsEnabled"=dword:00000001

Voir: https://blogs.msdn.Microsoft.com/jeremykuhne/2016/07/30/net-4-6-2-and-long-paths-on-windows-10/

4
Sergey Dryganets

Une autre façon de gérer ce problème consiste à utiliser Cygwin, en fonction de ce que vous voulez faire avec les fichiers (c.-à-d. 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, traitez leur contenu comme md5sum, grep, gzip, etc.

Pour les programmes que vous codez, vous pouvez également les lier au Cygwin DLL et leur permettre d’utiliser de longs chemins (je n’ai pas encore testé cela).

2
eliblanco87