Stworzyłem aplikację, która pobiera wszystkie biblioteki dokumentów ze strony SP, ale w pewnym momencie daje mi ten błąd (próbowałem spojrzeć na Google, ale nie mogłem nic znaleźć, teraz jeśli ktoś zna jakąś sztuczkę, aby rozwiązać ten problem, odpowiedz inaczej, dziękuję za obejrzenie tego)
System.IO.PathTooLongException: określona ścieżka, nazwa pliku lub obie są za długie. W pełni kwalifikowana nazwa pliku musi mieć mniej niż 260 znaków, a nazwa katalogu musi mieć mniej niż 248 znaków. w System.IO.Path.NormalizePathFast (ścieżka String, Boolean fullCheck) w System.IO.Path.GetFullPathInternal (ścieżka String) w System.IO.FileStream.Init (ścieżka ciągu, tryb FileMode, dostęp do pliku, prawa Int32, prawa do użycia logicznego , FileShare share, Int32 bufferSize, opcje FileOptions, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy) w System.IO.FileStream..ctor (ścieżka String, tryb FileMode, dostęp do FileAccess, udział FileShare, Int32 bufferSize, opcje FileOptions) w System. IO.File.Create (ścieżka ciągu)
osiąga limit dla ciągu, kod podano poniżej,
#region Downloading Schemes
private void btnDownload_Click(object sender, EventArgs e)
{
TreeNode currentNode = tvWebs.SelectedNode;
SPObjectData objectData = (SPObjectData)currentNode.Tag;
try
{
CreateLoggingFile();
using (SPWeb TopLevelWeb = objectData.Web)
{
if(TopLevelWeb != null)
dwnEachWeb(TopLevelWeb, TopLevelWeb.Title, tbDirectory.Text);
}
}
catch (Exception ex)
{
Trace.WriteLine(string.Format("Exception caught when tried to pass TopLevelWeb:{1}, Title = {2}, object data to (dwnEachWeb_method), Exception: {0}", ex.ToString(), objectData.Web, objectData.Title));
}
finally
{
CloseLoggingFile();
}
}
private void dwnEachWeb(SPWeb TopLevelWeb, string FolderName, string CurrentDirectory)
{
if (TopLevelWeb != null)
{
if (TopLevelWeb.Webs != null)
{
CurrentDirectory = CurrentDirectory + "\\" + TopLevelWeb.Title;
CreateFolder(CurrentDirectory);
foreach (SPWeb ChildWeb in TopLevelWeb.Webs)
{
dwnEachWeb(ChildWeb, ChildWeb.Title, CurrentDirectory);
ChildWeb.Dispose();
}
dwnEachList(TopLevelWeb, CurrentDirectory);
//dwnEachList(TopLevelWeb, FolderName, CurrentDirectory);
}
}
}
private void dwnEachList(SPWeb oWeb, string CurrentDirectory)
{
foreach (SPList oList in oWeb.Lists)
{
if (oList is SPDocumentLibrary && !oList.Hidden)
{
dwnEachFile(oList.RootFolder, CurrentDirectory);
}
}
}
private void dwnEachFile(SPFolder oFolder, string CurrentDirectory)
{
if (oFolder.Files.Count != 0)
{
CurrentDirectory = CurrentDirectory + "\\" + oFolder.Name;
CreateFolder(CurrentDirectory);
foreach (SPFile ofile in oFolder.Files)
{
if (CreateDirectoryStructure(CurrentDirectory, ofile.Url))
{
var filepath = System.IO.Path.Combine(CurrentDirectory, ofile.Url);
byte[] binFile = ofile.OpenBinary();
System.IO.FileStream fstream = System.IO.File.Create(filepath);
fstream.Write(binFile, 0, binFile.Length);
fstream.Close();
}
}
}
}
//creating directory where files will be download
private bool CreateDirectoryStructure(string baseFolder, string filepath)
{
if (!Directory.Exists(baseFolder)) return false;
var paths = filepath.Split('/');
for (var i = 0; i < paths.Length - 1; i++)
{
baseFolder = System.IO.Path.Combine(baseFolder, paths[i]);
Directory.CreateDirectory(baseFolder);
}
return true;
}
//creating folders
private bool CreateFolder(string CurrentDirectory)
{
if (!Directory.Exists(CurrentDirectory))
{
Directory.CreateDirectory(CurrentDirectory);
}
return true;
}
//shorting string
#endregion
Odpowiedzi:
Ponieważ przyczyna błędu jest oczywista, oto kilka informacji, które powinny pomóc w rozwiązaniu problemu:
Zobacz ten artykuł MS na temat nazewnictwa plików, ścieżek i przestrzeni nazw
Oto cytat z linku:
I kilka obejść (zaczerpniętych z komentarzy):
Istnieją sposoby rozwiązania różnych problemów. Podstawowa idea rozwiązań wymienionych poniżej jest zawsze taka sama: Zmniejsz długość ścieżki, aby mieć
path-length + name-length < MAX_PATH
. Możesz:źródło
Starting in Windows 10, version 1607, MAX_PATH limitations have been removed from common Win32 file and directory functions.
ale musisz wyrazić zgodę i ustawić klucz rejestru, aby go włączyć.Rozwiązaniem, które działało dla mnie, była edycja klucza rejestru, aby umożliwić zachowanie długiej ścieżki, ustawiając wartość na 1. Jest to nowa funkcja opt-in dla systemu Windows 10
HKLM\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled (Type: REG_DWORD)
Mam to rozwiązanie z nazwanej sekcji artykułu, który opublikował @ james-hill.
https://docs.microsoft.com/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation
źródło
<application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings xmlns:ws2="https://schemas.microsoft.com/SMI/2016/WindowsSettings"> <ws2:longPathAware>true</ws2:longPathAware> </windowsSettings> </application>
dla mnie w Visual Studio 2019 to drugie wymaganie nie było konieczne po ponownym uruchomieniu Visual Studio.Istnieje biblioteka o nazwie Zeta Long Paths, która zapewnia .NET API do pracy z długimi ścieżkami.
Oto dobry artykuł, który omawia ten problem zarówno dla platformy .NET, jak i programu PowerShell: „ .NET, zbyt długi wyjątek ścieżki programu PowerShell i klon robocopy programu PowerShell .NET ”
źródło
Możesz utworzyć dowiązanie symboliczne z krótszym katalogiem. Najpierw otwórz wiersz poleceń, na przykład
Shift + RightClick
w wybranym folderze z krótszą ścieżką (może być konieczne uruchomienie go jako administrator).Następnie wpisz ze ścieżkami względnymi lub bezwzględnymi:
A następnie zacznij Rozwiązanie od krótszej ścieżki. Zaleta jest taka: nie musisz niczego przenosić.
źródło
W systemie Windows 8.1 za pomocą. NET 3.5, miałem podobny problem.
Chociaż nazwa mojego pliku miała tylko 239 znaków długości, kiedy poszedłem do utworzenia wystąpienia obiektu FileInfo z samą nazwą pliku (bez ścieżki), wystąpił wyjątek typu System. IO.PathTooLongException
Rozwiązałem problem, skracając nazwę pliku do 204 znaków (łącznie z rozszerzeniem).
źródło
Jeśli masz problem z plikami bin z powodu długiej ścieżki, w programie Visual Studio 2015 możesz przejść do strony właściwości projektu i zmienić względny katalog wyjściowy na krótszy.
Np. Bin \ debug \ staje się C: \ _ bins \ MyProject \
źródło
Udało mi się przenieść projekt tak, jak był na pulpicie (C: \ Users \ lachezar.l \ Desktop \ MyFolder) do (C: \ 0 \ MyFolder), co, jak widać, używa krótszej ścieżki i zmniejszenie go rozwiązało problem.
źródło
Z mojego doświadczenia nie polecam mojej poniższej odpowiedzi dla żadnych publicznych aplikacji internetowych.
Jeśli potrzebujesz go do własnych narzędzi lub do testowania, polecam udostępnienie go na własnym komputerze.
Spowoduje to utworzenie katalogu współdzielonego, takiego jak \\ {PCName} \ {YourSharedRootDirectory}. Może to być zdecydowanie mniej niż pełna ścieżka, mam nadzieję, dla mnie mógłbym zmniejszyć do 30 znaków z około 290 znaków. :)
źródło
Jak dotąd nie wspominając o aktualizacji, istnieje bardzo dobrze rozwinięta biblioteka do obsługi zbyt długich ścieżek. AlphaFS to biblioteka .NET zapewniająca pełniejszą funkcjonalność systemu plików Win32 na platformie .NET niż standardowe klasy System.IO. Najbardziej zauważalną wadą standardowego .NET System.IO jest brak obsługi zaawansowanych funkcji NTFS, w szczególności obsługi rozszerzonych ścieżek (np. Ścieżki do plików / katalogów dłuższe niż 260 znaków).
źródło
Najlepsza odpowiedź, jaką mogę znaleźć, znajduje się w jednym z komentarzy tutaj. Dodanie go do odpowiedzi, aby ktoś nie przegapił komentarza i zdecydowanie powinien to wypróbować. Rozwiązało to dla mnie problem.
Musimy zmapować folder rozwiązania na dysk za pomocą polecenia „subst” w wierszu polecenia - np. Subst z:
A następnie otwórz rozwiązanie z tego dysku (w tym przypadku z). Skróciłoby to ścieżkę tak bardzo, jak to możliwe i mogłoby rozwiązać długi problem z nazwą pliku.
źródło
może to być również możliwe rozwiązanie. Czasami zdarza się również, gdy trzymasz projekt deweloperski zbyt głęboko, co oznacza, że może być możliwe, że katalog projektu może zawierać zbyt wiele katalogów, więc nie twórz zbyt wielu katalogów, przechowuj go w prostym folderze wewnątrz dyski. Na przykład - otrzymałem również ten błąd, gdy mój projekt był przechowywany w ten sposób-
D: \ Sharad \ LatestWorkings \ GenericSurveyApplication020120 \ GenericSurveyApplication \ GenericSurveyApplication
potem po prostu wkleiłem mój projekt do środka
D: \ Sharad \ LatestWorkings \ GenericSurveyApplication
I problem został rozwiązany.
źródło