Perché esiste il limite di lunghezza del percorso di 260 caratteri in Windows?


390

Mi sono imbattuto in questo problema alcune volte in momenti inopportuni:

  • Prova di lavorare su progetti Java open source con percorsi profondi
  • Memorizzazione di alberi wiki di Fitnesse profondi nel controllo del codice sorgente
  • Un errore nel tentativo di utilizzare Bazaar per importare il mio albero di controllo del codice sorgente

Perché esiste questo limite?

Perché non è stato ancora rimosso?

Come affrontate il limite del percorso? E no, il passaggio a Linux o Mac OS X non è una risposta valida a questa domanda;)


8
@Artelius: In realtà, Windows (almeno da Win2K in poi) supporta i punti di giunzione ( en.wikipedia.org/wiki/NTFS_junction_point ), e Vista in poi supporta i collegamenti simbolici NT ( en.wikipedia.org/wiki/NTFS_symbolic_link ). Ad ogni modo, mentre i collegamenti simbolici possono aiutare a rendere più amichevoli i percorsi più lunghi / nidificati, non riesco a pensare a come i collegamenti simbolici aiuterebbero se si rispettano i limiti di lunghezza del percorso.
Ashutosh Mehra,

8
Anche se questo limite non esistesse, ci sono sempre molti altri limiti e ognuno di essi potrebbe essere fastidioso ad un certo punto. Il punto è perché questo limite è così basso? Dopo l'era di 8.3, e con hardware di dimensioni mega / giga, un percorso dovrebbe ora essere una stringa allocata dinamicamente con una dimensione praticamente illimitata.
Roland,

12
Microsoft sta finalmente affrontando questo problema, in Windows 10 Build 14352.
Warren P

3
Sì, e sembra che tu debba modificare il manifest dell'app per renderlo consapevole del percorso lungo.
Warren P,

3
@PatrickSzalapski sfortunatamente è stato risolto visualstudio.uservoice.com/forums/121579-visual-studio/…
phuclv

Risposte:


231

Citando questo articolo https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#ma maximum-path-length- limitation

Limitazione della lunghezza massima del percorso

Nell'API di Windows (con alcune eccezioni discusse nei paragrafi seguenti), la lunghezza massima per un percorso è MAX_PATH , che è definita come 260 caratteri. Un percorso locale è strutturato nel seguente ordine: lettera di unità, due punti, barra rovesciata, componenti del nome separati da barre rovesciate e un carattere null terminante. Ad esempio, il percorso massimo sull'unità D è "D: \ una stringa di percorso di 256 caratteri <NUL>" dove "<NUL>" rappresenta il carattere null di terminazione invisibile per la tabella codici corrente del sistema. (I caratteri <> sono usati qui per chiarezza visiva e non possono far parte di una stringa di percorso valida.)

Ora vediamo che è 1 + 2 + 256 + 1 o [unità] [: \] [percorso] [null] = 260. Si potrebbe supporre che 256 sia una lunghezza di stringa fissa ragionevole dai giorni DOS. E tornando alle API DOS ci rendiamo conto che il sistema ha tracciato il percorso corrente per unità e abbiamo 26 (32 con simboli) numero massimo di unità (e directory correnti).

INT 0x21 AH = 0x47 dice "Questa funzione restituisce la descrizione del percorso senza la lettera di unità e la barra rovesciata iniziale." Quindi vediamo che il sistema memorizza il CWD come coppia (unità, percorso) e chiedi il percorso specificando l'unità (1 = A, 2 = B, ...), se specifichi uno 0 allora assume il percorso per l'unità restituita da INT 0x21 AH = 0x15 AL = 0x19. Quindi ora sappiamo perché è 260 e non 256, perché quei 4 byte non sono memorizzati nella stringa del percorso.

Perché una stringa di percorso a 256 byte, perché 640 KB è RAM sufficiente.


21
L'API di Windows limita la lunghezza, anche nel sistema operativo più recente. Microsoft ha paura di rompere centinaia di milioni di sistemi operativi in ​​uso oggi se questo dovesse cambiare perché non hanno più i geni che lavorano per loro che comprendono l'API dentro e fuori, come hanno fatto negli anni '80 e '90. Il rischio non vale la pena cambiarlo. serverfault.com/questions/163419/…
MacGyver

77
@MacGyver Siamo spiacenti, ma è una totale assurdità. Microsoft non vuole spezzare i milioni di applicazioni scritte male che assumono cose sul sistema che non sono mai state garantite. Sfortunatamente, le cose sono andate nello stesso modo per così tanto tempo che gli sviluppatori hanno iniziato a fare affidamento su di loro, quindi cambiarlo ora avrebbe spezzato le applicazioni di terze parti e MS avrebbe avuto la colpa.
Basic

25
tra l'altro non ci sono prove che Gates abbia mai detto che "640K Ram è abbastanza per tutti" computerworld.com/article/2534312
Patrick Favre,

11
@Basic Il limite di 260 caratteri era garantito da Windows. La costante è stata dichiarata come costante , una struttura è stata dichiarata nei file di intestazione di Windows che ha spazio solo per 260 caratteri. Non c'è modo di cambiarlo.
Ian Boyd,

35
@Basic La costante non cambia una volta compilata nella mia applicazione. Eseguo un'applicazione che è stata costruita l' ultima volta nel 1994 e funziona ancora oggi in Windows 10. Microsoft ha promesso una certa dimensione binaria di un blocco di memoria e il programmatore ha seguito quella regola. Se Microsoft dovesse cambiare la costante, allora ogni applicazione esistente, che seguiva correttamente l'API di programmazione, sarebbe rotta . Non è possibile interrompere la compatibilità binaria.
Ian Boyd,

150

Questo non è strettamente vero in quanto il filesystem NTFS supporta percorsi fino a 32k caratteri. È possibile utilizzare l'API win32 e il \\?\prefisso " " nel percorso per utilizzare più di 260 caratteri.

Una spiegazione dettagliata del lungo percorso dal blog del team .Net BCL .
Un piccolo estratto evidenzia il problema con percorsi lunghi

Un'altra preoccupazione è il comportamento incoerente che risulterebbe esponendo il supporto lungo percorso. I percorsi lunghi con il \\?\prefisso possono essere utilizzati nella maggior parte delle API di Windows relative ai file, ma non in tutte le API di Windows. Ad esempio, LoadLibrary, che associa un modulo all'indirizzo del processo di chiamata, ha esito negativo se il nome del file è più lungo di MAX_PATH. Quindi questo significa che MoveFile ti permetterà di spostare una DLL in una posizione tale che il suo percorso sia più lungo di 260 caratteri, ma quando provi a caricare la DLL, fallirebbe. Esistono esempi simili in tutte le API di Windows; esistono alcune soluzioni alternative, ma sono caso per caso.


4
Abbastanza giusto, ma significa che devi usare P / Invoke in molti posti e questo, a mio avviso, riduce la portabilità del tuo codice .Net. E se volessi mantenere la Mono-compatibilità?
Jeffrey Cameron,

1
Il mio punto era che puoi usare un percorso lungo se lo desideri davvero. Ma sono d'accordo che è un dolore e personalmente lo eviterei anche io.
softveda,

5
Questa dovrebbe essere la risposta scelta. Risponde effettivamente alla domanda posta dall'utente in merito al perché esiste questo limite E fornisce una soluzione. Miglioramento della visibilità
KyleMit

2
Mi sembra che Microsoft debba correggere le proprie API e immagino che questa non sia una priorità. Sono stato sorpreso che questo limite esista ancora in Windows 8.
Mas

3
@Mas La "correzione" che volevi è stata fatta su Windows XP. Chiamare la versione unicode della loro API ti permetterà di accedere al "percorso esteso". Credo che Explorer lo gestisca automaticamente. Ecco una di queste funzioni che la supporta: msdn.microsoft.com/en-us/library/windows/desktop/… .
Natalie Adams,

108

La domanda è: perché esiste ancora la limitazione. Sicuramente le moderne finestre possono aumentare il lato MAX_PATHper consentire percorsi più lunghi. Perché la limitazione non è stata rimossa?

  • Il motivo per cui non può essere rimosso è che Windows ha promesso che non cambierà mai.

Attraverso il contratto API, Windows ha garantito a tutte le applicazioni che le API dei file standard non restituiranno mai un percorso più lungo dei 260caratteri.

Considera il seguente codice corretto :

WIN32_FIND_DATA findData;

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

Windows ha garantito al mio programma che avrebbe popolato la mia WIN32_FIND_DATAstruttura:

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

La mia applicazione non ha dichiarato il valore della costante MAX_PATH, l'API di Windows l'ha fatto. La mia applicazione ha usato quel valore definito.

La mia struttura è definita correttamente e alloca solo i 592byte totali. Ciò significa che sono in grado di ricevere solo un nome file inferiore a 260caratteri. Windows mi ha promesso che se avessi scritto la mia domanda correttamente, la mia applicazione avrebbe continuato a funzionare in futuro.

Se Windows dovesse consentire nomi di file più lunghi dei 260caratteri, la mia applicazione esistente (che utilizzava correttamente l'API corretta) avrebbe esito negativo.

Per chiunque richieda a Microsoft di modificare la MAX_PATHcostante, è necessario innanzitutto assicurarsi che nessuna applicazione esistente abbia esito negativo. Ad esempio, possiedo ancora e utilizzo un'applicazione Windows scritta per l'esecuzione su Windows 3.11. Funziona ancora su Windows 10 a 64 bit. Questo è ciò che ti rende compatibile con le versioni precedenti.

Microsoft ha creato un modo per utilizzare i 32.768 nomi di percorso completi; ma hanno dovuto creare un nuovo contratto API per farlo. Per uno, è necessario utilizzare l' API Shell per enumerare i file (poiché non tutti i file esistono su un disco rigido o una condivisione di rete).

Ma devono anche non rompere le applicazioni utente esistenti. La stragrande maggioranza delle applicazioni non utilizza l'API della shell per il lavoro dei file. Tutti chiamano FindFirstFile/ FindNextFilee lo chiamano un giorno.


4
@JosiahKeller Se lo facesse, si spezzerebbe il contratto originariamente definito per quel metodo e, facendo ciò, si potrebbe sovrascrivere la memoria non intenzionale e aprire potenzialmente una falla di sicurezza. L'unico modo per risolvere questo problema è offrire una nuova API migliorata (come le varianti compatibili con Unicode) e sperare che tutti ricompilino / rilasci tutte le loro applicazioni utilizzando l'API più recente.
Rowland Shaw,

2
@Ryios Non penso che le mie applicazioni Windows esistenti funzioneranno su Linux.
Ian Boyd,

9
La compatibilità con le versioni precedenti è buona. Ma penso che evitare tali problemi (spesso davvero cattivi) oggi sia più importante del supporto delle applicazioni Windows 3.1. Quante persone incontrano problemi con percorsi lunghi? E quante persone usano ancora le applicazioni Windows 3.1? Annullano persino il supporto per Windows XP. Quindi perché non danno solo un annuncio, che da Windows [x] e dalle applicazioni successive che presumono che non ci sarà un percorso più lungo di 260 caratteri, non funzionerà come previsto quando incontrano un percorso troppo lungo? Anche i nostri limiti di velocità non riguardano le carrozze.
JuSchu,

2
@JuSchu Non sono solo applicazioni Windows 3.1. Le applicazioni scritte oggi utilizzando l'API corretta non funzioneranno.
Ian Boyd,


62

Da Windows 10. è possibile rimuovere la limitazione modificando una chiave di registro.

Suggerimento A partire da Windows 10, versione 1607, le limitazioni MAX_PATH sono state rimosse dalle comuni funzioni di file e directory Win32. Tuttavia, è necessario attivare il nuovo comportamento.

Una chiave di registro consente di abilitare o disabilitare il nuovo comportamento del percorso lungo. Per abilitare il comportamento lungo percorso, impostare la chiave del Registro di sistema su HKLM\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled(Tipo:) REG_DWORD. Il valore della chiave verrà memorizzato nella cache dal sistema (per processo) dopo la prima chiamata a un file Win32 interessato o alla funzione di directory (l'elenco segue). La chiave di registro non verrà ricaricata durante il ciclo di vita del processo. Affinché tutte le app sul sistema riconoscano il valore della chiave, potrebbe essere necessario un riavvio perché alcuni processi potrebbero essere stati avviati prima dell'impostazione della chiave. La chiave di registro può anche essere controllata tramite Criteri di gruppo in Computer Configuration > Administrative Templates > System > Filesystem > Enable NTFS long paths. Puoi anche abilitare il nuovo comportamento del percorso lungo per app tramite manifest:

<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>

15
Purtroppo anche nell'ultima versione Win10, lo stesso Esplora file ha ancora problemi a gestire il nome del percorso lungo. Anche "Copia come percorso" nel menu di scelta rapida non funziona come previsto; copia solo i primi 260 caratteri. Non è possibile creare cartelle, copiare / spostare / aprire file ... Mi chiedo quale sia il punto di questo cambiamento.
raymai97,

Si noti che l'affermazione secondo cui l'impostazione di sistema è indipendente dall'impostazione manifest è errata. Entrambi sono richiesti. Il criterio deve essere abilitato a livello di sistema e il manifest deve dichiarare che l'applicazione è a conoscenza del percorso lungo.
Eryk Sun

Ho letto che apportare questa modifica potrebbe causare problemi di compatibilità con le vecchie applicazioni a 32 bit, ma questo tipo di problema con la compatibilità è comune? Mi piacerebbe fare il cambiamento da solo. lifehacker.com/…
KDP

32

È possibile montare una cartella come unità. Dalla riga di comando, se hai un percorso C:\path\to\long\folderpuoi mapparlo per guidare la lettera X:usando:

subst x: \path\to\long\folder


Questo deve essere eseguito da un prompt dei comandi dell'amministratore (elevato).
Mrchief,

Questo fallirà con le barre in avanti, deve essere una barra rovesciata.
cchamberlain,

1
Non sono sicuro se questo si applica solo a Windows 10, tuttavia ho appena scoperto che quando provo a eseguire questo comando, se corro come amministratore come suggerito sopra, l'unità non sembra essere disponibile. Questo perché il comportamento sembra essere simile al mapping di un'unità di rete ed è specifico della sessione, ecc. Quindi, quando ho eseguito come amministratore e utilizzato questo comando, quella sessione potrebbe utilizzare x: TL; DR Se non riesci a vedere l'unità prova eseguendo il comando senza essere in modalità amministratore.
Jaddie,

substè local-session / account - vedi superuser.com/questions/29072/… per come renderlo "di sistema"
user2864740

18

Un modo per far fronte al limite del percorso è abbreviare le voci del percorso con collegamenti simbolici.

Per esempio:

  1. creare una C:\pdirectory per mantenere collegamenti brevi a percorsi lunghi
  2. mklink /J C:\p\foo C:\Some\Crazy\Long\Path\foo
  3. aggiungi C:\p\fooal tuo percorso invece del lungo percorso

3
Non è stato necessario creare prima la directory, quindi il passaggio 1 non è necessario.
ohaal,

2
Questo trucco non funziona sempre poiché molte applicazioni cercano di risolvere i collegamenti
nponeccop,

L' /jopzione crea un mountpoint di giunzione per un dispositivo volume locale o un percorso su un volume locale (come un mount bind Unix). Non crea un collegamento simbolico. È una distinzione importante poiché i mountpoint di giunzione vengono sempre valutati su un server e devono essere indirizzati ai dispositivi locali, mentre i collegamenti simbolici vengono valutati sul client e possono indirizzare percorsi remoti (se consentito dalla politica). Come un'unità subst.exe (ovvero DefineDosDeviceW), una destinazione di giunzione è in genere limitata a circa 4K caratteri. In realtà sono 8K caratteri, suddivisi in modo uniforme tra il percorso sostitutivo e il percorso di visualizzazione.
Eryk Sun,

12

È possibile abilitare i nomi di percorsi lunghi utilizzando PowerShell:

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

Un'altra versione è utilizzare un criterio di gruppo in Computer Configuration/ Administrative Templates/ System/ Filesystem:

Editor dei criteri di gruppo


2
Ogni applicazione deve ancora dichiarare che è consapevole del percorso lungo. Microsoft ha fatto un pessimo lavoro comunicandolo facendo sembrare che il manifest dell'applicazione sia solo un altro modo per abilitare questa funzionalità, piuttosto che spiegare chiaramente che si tratta di un contratto tra il sistema operativo (politica a livello di sistema) e l'applicazione in cui entrambi devono concordare.
Eryk Sun,

8

Per quanto riguarda il motivo per cui questo esiste ancora: MS non lo considera una priorità e apprezza la retrocompatibilità rispetto all'avanzamento del proprio sistema operativo (almeno in questo caso).

Una soluzione alternativa che utilizzo consiste nell'utilizzare i "nomi brevi" per le directory nel percorso, anziché le loro versioni standard leggibili dall'uomo. Quindi, per esempio,C:\Program Files\ vorrei usare C:\PROGRA~1\ Puoi trovare gli equivalenti dei nomi brevi usando dir /x.


1
I nomi di percorsi brevi possono essere disabilitati nel registro (o era il file system stesso?), Quindi non si tratta di una soluzione affidabile.
rubenvb,

3
@rubenvb Sono sicuro che la maggior parte se non tutte le funzionalità di Windows possono essere disabilitate nel registro, quindi ¯ \ _ (ツ) _ / ¯
Conrad

La generazione di nomi brevi può essere disabilitata per NTFS (e dovrebbe essere perché è inefficiente in molti casi), per l'intero sistema o per volume, quindi è un approccio inaffidabile anche per i percorsi sull'unità di sistema, che deve essere NTFS. È possibile impostare manualmente nomi brevi su file e directory in NTFS, ma ciò non si estende ai file system più recenti che non supportano affatto i nomi brevi, come exFAT e ReFS. I nomi brevi devono essere considerati una funzionalità obsoleta che viene mantenuta per la compatibilità in casi limitati, come la vecchia API ANSI / OEM che utilizza le tabelle codici a singolo e doppio byte.
Eryk Sun,

@eryksun Si prega di consultare il mio commento precedente sulla disabilitazione dei nomi di percorsi brevi. :) Solo perché pensi che dovrebbe essere considerato deprecato, non significa che lo sia davvero. MS non ha in programma di deprecare questa funzionalità. (Inoltre, perché stai installando il software Windows su partizioni exFAT / ReFS?)
Conrad,

Dico ancora di utilizzare solo percorsi di dispositivi non normalizzati (ad esempio prefisso "\\? \"), Poiché sono sempre disponibili e ovvi. Ad esempio, traduci PATHe passalo a SearchPathW. È anche efficiente, poiché la libreria di runtime crea comunque "\\? \" Percorsi dispositivo per NT. Per quanto riguarda i filesystem più recenti, probabilmente non vedremmo software installato su un volume exFAT, oltre alle applicazioni portatili, dal momento che non ha sicurezza, ma non escluderei ReFS. Gli utenti installano programmi in posizioni non standard per motivi di convenienza, spazio o prestazioni.
Eryk Sun,

7

Come affrontare la limitazione della dimensione del percorso su Windows: usare 7zip per comprimere (e decomprimere) i file sensibili alla lunghezza del percorso sembra una soluzione possibile. L'ho usato per trasportare diverse installazioni IDE (quei percorsi dei plugin Eclipse, yikes!) E pile di documentazione generata automaticamente e finora non ho avuto un singolo problema.

Non sono sicuro di come elimini il limite di 260 caratteri impostato da Windows (da un PoV tecnico), ma, ehi, funziona!

Maggiori dettagli sulla loro pagina SourceForge qui :

"NTFS può effettivamente supportare percorsi con una lunghezza massima di 32.000 caratteri."

7-zip supporta anche nomi così lunghi.

Ma è disabilitato nel codice SFX. Ad alcuni utenti non piacciono i percorsi lunghi, poiché non capiscono come lavorare con loro. Ecco perché l'ho disabilitato nel codice SFX.

e note di rilascio :

9.32 alpha 2013-12-01

  • Supporto migliorato per nomi di file di lunghezza superiore a 260 caratteri.

4.44 beta 20/01/2007

  • 7-Zip ora supporta nomi di file più lunghi di 260 caratteri.

NOTA IMPORTANTE: affinché funzioni correttamente, è necessario specificare direttamente il percorso di destinazione nella finestra di dialogo "Estrai" di 7zip , anziché trascinare e rilasciare i file nella cartella desiderata. Altrimenti la cartella "Temp" verrà utilizzata come cache temporanea e rimbalzerai nella stessa limitazione di 260 caratteri una volta che Esplora risorse inizierà a spostare i file nella loro "posizione di riposo finale". Vedi le risposte a questa domanda per maggiori informazioni.


3
Ho sbagliato, 7zip e WinRAR estraggono tutte le cartelle e i file. È solo che la proprietà di una cartella in Windows riporta solo il numero di cartelle e file che non violano la limitazione. È come se Windows Explorer non scava più a fondo per scoprire le cartelle quando viene raggiunto il percorso massimo.
Twisted Whisper,

È possibile eliminare un percorso lungo in 7-zip con shift-del.
Laurie Stearn,

Risposta breve: usa 7zip per decomprimere un file .zip .... ha funzionato per me su Windows 7
andrewcockerham,


2

Un altro modo per affrontarlo è usare Cygwin, a seconda di cosa vuoi fare con i file (cioè se i comandi Cygwin soddisfano le tue esigenze)

Ad esempio, consente di copiare, spostare o rinominare i file che nemmeno Windows Explorer può fare. O ovviamente gestirne i contenuti come md5sum, grep, gzip, ecc.

Anche per i programmi che stai codificando, potresti collegarli alla DLL Cygwin e consentirebbe loro di utilizzare percorsi lunghi (non l'ho ancora testato)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.