Wie kann System.IO.PathTooLongException vermieden werden?

Wir stoßen ständig auf dieses Problem …

Beispiel:

Wenn ich eine Datei habe, die ich in ein anderes Verzeichnis oder eine UNC-Freigabe kopieren möchte und wenn die Länge des Pfades 248 überschreitet (wenn ich mich nicht irre), wird PathTooLongException ausgetriggers. Gibt es eine Problemumgehung für dieses Problem?

PS: Gibt es Registrierungseinstellungen, um diesen Pfad auf einen längeren Zeichensatz zu setzen?

Wie in Jeremy Kuhnes Blog beschrieben , entfernt .NET Framework 4.6.2 die MAX_PATH Einschränkung wo möglich, ohne die Abwärtskompatibilität zu MAX_PATH .

Versuchen Sie dies: Delimon.Win32.I O Bibliothek (V4.0) Diese Bibliothek ist auf .NET Framework 4.0 geschrieben

Delimon.Win32.IO ersetzt die grundlegenden Dateifunktionen von System.IO und unterstützt Datei- und Ordnernamen mit bis zu 32.767 Zeichen.

https://gallery.technet.microsoft.com/DelimonWin32IO-Library-V40-7ff6b16c

Diese Bibliothek wurde speziell geschrieben, um die Einschränkungen von .NET Framework für die Verwendung langer Pfad- und Dateinamen zu überwinden. Mit dieser Bibliothek können Sie Dateien und Ordner, auf die die System.IO-Namespace.Library nicht zugreifen kann, programmgesteuert durchsuchen, darauf zugreifen, sie schreiben, löschen usw.

Verwendung

  1. Fügen Sie zuerst einen Verweis auf die Delimon.Win32.IO.dll zu Ihrem Projekt hinzu (Durchsuchen Sie die Delimon.Win32.IO.dll-Datei)

  2. Fügen Sie in Ihrer Codedatei “Delimon.Win32.IO” hinzu

  3. Verwenden Sie normale Datei- und Verzeichnisobjekte, als ob Sie mit System.IO arbeiten

Dies wurde ausführlich vom BCL-Team diskutiert, siehe Blogeinträge

Im Wesentlichen gibt es keine Möglichkeit, dies innerhalb. NET-Code zu tun und bei der BCL bleiben. Zu viele functionen beruhen darauf, dass der Pfadname kanonisiert werden kann (was sofort die Verwendung von functionen austriggers, die erwarten, dass MAX_PATH befolgt wird).

Sie könnten alle win32-functionen umschließen, die die Syntax “\\” unterstützen, mit denen Sie in der Lage wären, eine Reihe von functionen mit langem Pfad zu implementieren, aber das wäre umständlich.

Da eine große Anzahl von Tools (einschließlich Explorer [1]) lange Pfadnamen nicht verarbeiten kann, ist es nicht ratsam, diesen Weg zu gehen, es sei denn, Sie sind froh, dass alle Interaktionen mit dem resultierenden Dateisystem durch Ihre Bibliothek gehen (oder die begrenzte Anzahl von Tools, die sind gebaut, um es wie Robocopy zu behandeln)

Als Antwort auf Ihre spezifischen Anforderungen würde ich untersuchen, ob die Verwendung von Robocopy direkt ausreicht, um diese Aufgabe zu erfüllen.

[1] Vista hat Möglichkeiten, das Problem mit einer gewissen Umbenennung unter der Haube zu mildern, aber das ist bestenfalls fragil)

Nur eine Problemumgehung, die ich in diesem Artikel gesehen habe, könnte hilfreich sein

http://www.codeproject.com/KB/files/LongFileNames.aspx

Das Problem liegt bei den ANSI-Versionen der Windows-APIs. Eine Lösung, die sorgfältig getestet werden muss, ist die Verwendung von Unicode-Versionen der Windows-API. Dies kann durch Voranstellen von ” \\?\ ” an den abgefragten Pfad erfolgen.

In den folgenden Blogposts aus dem Microsoft Base Class Library (BCL) -Team mit dem Titel “Long Paths in .NET” finden Sie große Informationen, einschließlich Arbeitsumgebungen:

Ich habe den Befehl “subst” verwendet, um das Problem zu umgehen … http://www.techrepublic.com/article/mapping-drive-letters-to-local-folders-in-windows-xp/5975262

Diese Bibliothek könnte hilfreich sein: Zeta Long Paths

In C # für mich ist dies ein Workaround:

 /*make long path short by setting it to like cd*/ string path = @"\\godDamnLong\Path\"; Directory.SetCurrentDirectory(path); 

Meine Drive-Mapping-Lösung funktioniert gut und stabil mit “NetWorkDrive.cs” und “NetWorkUNCPath.cs”, die von https://www.mycsharp.de/wbb2/thread.php?postid=3807703#post3807703 heruntergeladen werden können

Testbeispiel:

 if (srcFileName.Length > 260) { string directoryName = srcFileName.Substring(0, srcFileName.LastIndexOf('\\')); var uncName = GetUNCPath(srcFileName.Substring(0, 2)) + directoryName.Substring(2); using (NetWorkDrive nDrive = new NetWorkDrive(uncName)) { drvFileName = nDrive.FullDriveLetter + Path.GetFileName(sourceFileName) File.Copy(drvFileName, destinationFileName, true); } } else { File.Copy(srcFileName, destinationFileName, true); }