30 votes

Dois-je traiter les fichiers dont la longueur est supérieure à MAX_PATH ?

J'ai eu un cas intéressant.

Mon logiciel a signalé un échec causé par un chemin plus long que MAX_PATH.

Le chemin d'accès était simplement un vieux document dans Mes documents, par exemple :

C:\Documents and Settings\Bill\Some Stupid FOlder Name\A really ridiculously long file thats really very very very..........very long.pdf

Longueur totale de 269 caractères (MAX_PATH==260).

L'utilisateur n'utilisait pas un disque dur externe ou quelque chose comme ça. Il s'agissait d'un fichier sur un disque géré par Windows.

Alors ma question est la suivante. Dois-je m'en soucier ?

Je ne dis pas peut Je m'occupe des longs chemins, je demande debe I. Oui, je suis au courant du piratage de l'unicode "\?\" sur certaines API Win32, mais il semble que ce piratage n'est pas sans risque (car il modifie le comportement de la façon dont les API analysent les chemins) et n'est pas non plus pris en charge par toutes les API .

Quoi qu'il en soit, permettez-moi d'exposer ma position et mes affirmations :

  1. D'abord, on peut supposer que la seule façon dont l'utilisateur a pu dépasser cette limite est que l'application qu'il a utilisée utilise le hack spécial Unicode. Il s'agit d'un fichier PDF, donc peut-être que l'outil PDF qu'elle a utilisé utilise ce piratage.
  2. J'ai essayé de reproduire cela (en utilisant le hack unicode) et j'ai expérimenté. Ce que j'ai trouvé, c'est que bien que le fichier apparaisse dans l'explorateur, je ne peux rien en faire. Je ne peux pas l'ouvrir, je ne peux pas choisir "Propriétés" (Windows 7). D'autres applications courantes ne peuvent pas ouvrir le fichier (par exemple, IE, Firefox, Notepad). L'explorateur ne me laisse pas non plus créer des fichiers/répertoires trop longs - il refuse tout simplement. Idem pour l'outil de ligne de commande cmd.exe.

En gros, on pourrait voir les choses ainsi : un outil rouge a permis à l'utilisateur de créer un fichier qui n'est pas accessible par un grand nombre de Windows (par exemple, l'Explorateur). Je pourrais me dire que je ne devrais pas avoir à m'occuper de cela.

(En passant, il ne s'agit pas d'un vote d'approbation pour une longueur maximale de chemin courte : Je pense que 260 caractères est une plaisanterie, je dis simplement que si le shell Windows et certaines API ne peuvent pas gérer > 260 alors pourquoi le ferais-je ?).

Alors, est-ce un point de vue juste ? Devrais-je dire "Pas mon problème" ?

UPDATE : Un autre utilisateur a eu le même problème. Cette fois, il s'agissait d'un fichier mp3. Est-ce que quelque chose m'échappe ? Comment ces utilisateurs peuvent-ils créer des fichiers qui violent la règle MAX_PATH ?

9 votes

Il est facile de créer un fichier dont le nom est trop long : il suffit de renommer l'un de ses répertoires ancêtres pour qu'il soit suffisamment long pour faire basculer le fichier. Dans votre exemple : rename "C:\Documents and Settings\Bill\New Folder" "Some Stupid FOlder Name" .

11voto

Oleg Points 136406

Ce n'est pas un réel problème. NTFS supporte les noms de fichiers jusqu'à 32K ( 32 767 caractères larges ). Il vous suffit d'utiliser l'API correcte et la syntaxe correcte des noms de fichiers. La règle de base est la suivante : le nom de fichier doit commencer par '\\?\' (voir http://msdn.microsoft.com/en-us/library/aa365247(v=VS.85).aspx ) comme \\?\C:\Temp . La même syntaxe que vous pouvez utiliser avec UNC : \\?\UNC\Server\share\Path . Il est important de comprendre que vous ne pouvez utiliser qu'un petit sous-ensemble de fonctions de l'API. Par exemple, consultez la description des fonctions dans le MSDN.

CreateFile
CreateDirectory 
MoveFile

et ainsi de suite

vous trouverez des textes comme :

Dans la version ANSI de cette fonction, le nom est limité à MAX_PATH caractères. Pour étendre cette limite à 32 767 caractères larges, appelez la version Unicode de la fonction et ajoutez "\?\" au chemin d'accès. Pour plus d'informations informations, consultez la section Nommer un fichier.

Cette fonction vous permet de l'utiliser en toute sécurité. Si vous avez un handle de fichier de CreateFile vous pouvez utiliser toutes les autres fonctions utilisées hFile ( ReadFile , WriteFile etc.) sans aucune restriction.

Si vous écrivez un programme comme un scanner de virus ou un logiciel de sauvegarde ou tout autre bon logiciel fonctionnant sur un serveur, vous devez écrire votre programme de sorte que toutes les opérations sur les fichiers supportent les noms de fichiers jusqu'à 32K et non pas MAX_PATH des personnages.

4 votes

Bonjour, merci pour le commentaire. Oui, je sais que ces API existent (voir mon article). Je ne pense pas que l'on puisse commencer à utiliser ce hack et s'attendre à ce que tout se passe bien. Par exemple, l \\ Le hack supprime une partie de l'analyse. De plus, je ne vois pas très bien comment la SORTIE des API est affectée. Je ne vois pas très bien quel est l'impact de cette modification. Si je m'engage dans cette voie, je devrai effectuer de nombreux tests. Avez-vous l'expérience de l'utilisation de ces API ?

7 votes

@John. Vous comprenez mal comment la manière avec " \\ ?\" fonctionne. Il s'agit NO un piratage ! Il s'agit d'un moyen bien documenté de travailler directement avec l'API native de Windows NT (à partir de ntdll.dll) comme NtCreateFile. msdn.microsoft.com/fr/us/library/bb432380%28VS.85%29.aspx . Si vous utilisez cette fonction, vous recevrez pas moins de sécurité, mais seulement moins de confort . La plupart des API Windows datent de l'époque de Windows 3.0 16 bits et comportent une restriction MAX_PATH. L'API native de Windows NT (à partir de ntdll.dll) est principalement utilisée pour la programmation de pilotes. Ainsi, l'utilisation de " \\ ?\" est sûr. J'ai plus de 15 ans d'expérience dans l'utilisation de ce produit.

4 votes

OK, oui, "hack" est probablement le mauvais terme :) Ce que je dis cependant, c'est qu'il ne s'agit PAS d'un simple remplacement. Par exemple, les chemins relatifs ne fonctionneront pas, si vous utilisez "." ou ".." dans un chemin, cela ne fonctionnera pas. Certaines API modifieront également le SORTIE (OUTPUT) si vous utilisez cette "fonctionnalité" (par exemple, GetLongPathName() renverra les chemins qui incluent le ". \\ ?\"). D'un autre côté, il est bon d'entendre que vous avez 15 ans d'expérience dans l'utilisation de cette API - cela me rassure beaucoup.

10voto

Hans Passant Points 475940

Cette limitation est intégrée dans une lot de logiciels écrits en C ou C++. Y compris le code de MSFT, bien qu'ils y aient remédié. Ce n'est qu'en partie une limitation de Win32, qui a toujours une limite supérieure stricte sur la longueur d'un nom de fichier (et non d'un chemin) via WIN32_FIND_DATA par exemple. L'une des raisons pour lesquelles même .NET a restrictions de longueur . Ce n'est pas près de disparaître, Win32 est toujours aussi puissant et la chaîne C de l'âge de pierre ne disparaîtra pas.

Votre client aura sans doute peu de sympathie pour ce programme, probablement jusqu'à ce que vous puissiez lui montrer un autre programme qui échoue de la même manière. Assurez-vous cependant que votre code peut détecter de manière fiable le dépassement potentiel de la mémoire tampon d'une chaîne de caractères, suivi d'un diagnostic raisonnable. Aucune sympathie pour les programmes qui bombardent sur la corruption du tas.

0 votes

Bonjour Hans, merci pour la réponse. Vous m'aidez à résoudre quelques problèmes en ce moment ! Merci !

6voto

Stephen Nutt Points 2453

Comme vous l'avez mentionné, de nombreuses fonctions du shell Windows ne fonctionnent que sur des chemins allant jusqu'à MAX_PATH. Windows XP et, je crois, Vista ont tous deux des problèmes dans l'Explorateur lorsqu'ils imbriquent des répertoires avec des noms de fichiers longs. Je n'ai pas vérifié Windows 7 - peut-être ont-ils corrigé ce problème. Cela signifie malheureusement que les utilisateurs ont du mal à parcourir ces fichiers.

Si vous souhaitez vraiment prendre en charge les longs chemins, vous devrez vérifier toutes les fonctions de Shell32.dll qui prennent en charge les chemins pour vous assurer qu'elles prennent en charge les longs chemins. Pour celles qui ne le font pas, vous devrez les écrire vous-même en utilisant les fonctions Kernel32.

Si vous décidez d'utiliser Shell32 et d'être limité à MAX_PATH, il est conseillé d'écrire votre code pour supporter les longs chemins de fichiers. Si Microsoft modifie ultérieurement Shell32 (ou crée une alternative), vous serez mieux placé pour ajouter leur prise en charge.

Pour ajouter quelques dimensions supplémentaires au problème, rappelez-vous que les noms de fichiers sont UTF-16, et que vous pouvez rencontrer des systèmes de fichiers non NTFS ou FAT qui peuvent être sensibles à la casse !

1 votes

Oui, le shell de Windows 7 est toujours le même. Non seulement il vous empêche de créer des fichiers/dossiers trop longtemps, mais s'il en trouve un qui existe, vous ne pouvez rien en faire (vous ne pouvez même pas le supprimer !).

0 votes

Merci pour la vérification, c'est bon de savoir ce dont le 7 est capable, bien que décevant qu'il souffre de la même restriction.

5voto

Michael Aaron Safyan Points 45071

Vos propres API ne devraient pas coder en dur une limite fixe sur la longueur du chemin (ou toute autre limite dure) ; cependant, vous ne devriez pas violer les conditions préalables des API du système afin d'accomplir une certaine tâche. À mon avis, le fait que Windows limite la longueur des noms de chemin est absurde et devrait être considéré comme un bogue. Cela dit, je vous suggère de ne pas essayer d'utiliser les diverses API système autrement que comme elles sont documentées, même si cela entraîne un comportement indésirable tel que la limitation de la longueur maximale des chemins. Donc, en résumé, votre point de vue est tout à fait juste : si le système d'exploitation ne le prend pas en charge, alors le système d'exploitation ne le prend pas en charge. Cela dit, vous voudrez peut-être faire comprendre aux utilisateurs qu'il s'agit d'une limitation de Windows et non de votre propre code.

2voto

Helge Klein Points 3939

Un moyen simple de créer ces fichiers avec de longs chemins d'accès, même avec un logiciel qui ne prend pas en charge les chemins d'accès plus longs que MAX_PATH, consiste à utiliser un partage de fichiers.

Exemple :

" C:\My un très long dossier" pourrait être partagé comme "données". Les utilisateurs pourraient alors accéder à ce dossier par le chemin UNC \\computer\data ou (encore plus court) via une lettre de lecteur (M:\) en supposant que M : est mappé sur \\computer\data.

Cela se produit souvent sur les serveurs de fichiers.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X