Reputation: 2010
I created a app that downloads all document libraries in a SP Site , but at one point it giving me this error (I tried looking at google but couldn;t find anything, now if anyone knows any trick to solve this problem please respond otherwise thanks for looking at it)
System.IO.PathTooLongException: The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters. at System.IO.Path.NormalizePathFast(String path, Boolean fullCheck) at System.IO.Path.GetFullPathInternal(String path) at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy) at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options) at System.IO.File.Create(String path)
it reaches the limit for string, Code is given below,
#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
Upvotes: 139
Views: 372394
Reputation: 1236
Here are the tasks (verified that it works for long file paths) in addition to the previous answer:
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows;
namespace SymlinkCreator.ui.utility
{
internal static class LongPathAware
{
#region constants
private const string ShellIdListArrayName = "Shell IDList Array";
private const uint SIGDN_FILESYSPATH = 0x80058000;
#endregion
#region methods
public static IEnumerable<string> GetPathsFromShellIdListArray(IDataObject data)
{
if (!data.GetDataPresent(ShellIdListArrayName)) yield break;
using (MemoryStream ms = (MemoryStream)data.GetData(ShellIdListArrayName))
{
byte[] bytes = ms.ToArray();
IntPtr p = Marshal.AllocHGlobal(bytes.Length);
try
{
Marshal.Copy(bytes, 0, p, bytes.Length);
uint cidl = (uint)Marshal.ReadInt32(p);
int offset = sizeof(uint);
IntPtr parentpidl = (IntPtr)((long)p + Marshal.ReadInt32(p, offset));
for (int i = 1; i <= cidl; ++i)
{
offset += sizeof(uint);
IntPtr relpidl = (IntPtr)((long)p + Marshal.ReadInt32(p, offset));
IntPtr abspidl = ILCombine(parentpidl, relpidl);
if (abspidl == IntPtr.Zero) continue;
if (SHGetNameFromIDList(abspidl, SIGDN_FILESYSPATH, out IntPtr pszName) == 0)
{
yield return Marshal.PtrToStringUni(pszName);
Marshal.FreeCoTaskMem(pszName);
}
ILFree(abspidl);
}
}
finally
{
Marshal.FreeHGlobal(p);
}
}
}
#endregion
#region external methods
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
public static extern int SHGetNameFromIDList(IntPtr pidl, uint sigdnName, out IntPtr ppszName);
[DllImport("shell32.dll")]
public static extern IntPtr ILCombine(IntPtr pidl1, IntPtr pidl2);
[DllImport("shell32.dll")]
public static extern void ILFree(IntPtr pidl);
#endregion
}
}
private string[] GetDroppedFileOrFolderList(DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
try
{
return (string[])e.Data.GetData(DataFormats.FileDrop);
}
catch (COMException) // Handle long-path scenarios
{
return LongPathAware.GetPathsFromShellIdListArray(e.Data).ToArray();
}
}
return null;
}
private void SourceFileOrFolderListView_OnDrop(object sender, DragEventArgs e)
{
string[] droppedFileOrFolderList = GetDroppedFileOrFolderList(e);
if (droppedFileOrFolderList != null)
{
// Do something here
}
}
This should return the long path list as expected (it works well even for more than one dropped file).
Credit: The answer was inspired from another StackOverflow question's answer.
Upvotes: 0
Reputation: 137
The folowing worked with me on Windows 10 using visual studio 2022 :
run the following powershell script :
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" ` -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
restart your pc and run visual studio again.
if you dont want to change the registery move the project to a shorter path destination.
Upvotes: 0
Reputation: 1756
The solution that worked for me was to edit the registry key to enable long path behaviour, setting the value to 1. This is a new opt-in feature for Windows 10
HKLM\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled (Type: REG_DWORD)
I got this solution from a named section of the article that @james-hill posted.
In editions of Windows before Windows 10 version 1607, the maximum length for a path is MAX_PATH, which is defined as 260 characters. In later versions of Windows, changing a registry key or using the Group Policy tool is required to remove the limit. See Maximum Path Length Limitation for full details.
See also Maximum Path Length Limitation mentioned by @dontbyteme.
To enable the new long path behavior, both of the following conditions must be met:
- The registry key
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled (Type: REG_DWORD)
must exist and be set to 1. The key's value will be cached by the system (per process) after the first call to an affected Win32 file or directory function (see below for the list of functions). The registry key will not be reloaded during the lifetime of the process. In order for all apps on the system to recognize the value of the key, a reboot might be required because some processes may have started before the key was set.- The application manifest must also include the
longPathAware
element.<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>
Upvotes: 60
Reputation: 7693
Apps that target the .NET Framework 4.6.2 and later versions Long paths are supported by default. The runtime throws a PathTooLongException under the following conditions:
https://learn.microsoft.com/en-us/dotnet/api/system.io.pathtoolongexception?view=net-6.0
Upvotes: 0
Reputation: 13
this may be also possibly solution.It some times also occurs when you keep your Development project into too deep, means may be possible project directory may have too many directories so please don't make too many directories keep it in a simple folder inside the drives. For Example- I was also getting this error when my project was kept like this-
D:\Sharad\LatestWorkings\GenericSurveyApplication020120\GenericSurveyApplication\GenericSurveyApplication
then I simply Pasted my project inside
D:\Sharad\LatestWorkings\GenericSurveyApplication
And Problem was solved.
Upvotes: 0
Reputation: 1103
From my experience, won't recommend my below answer for any public facing Web applications.
If you need it for your inhouse tools or for Testing, I would recommend to share it on your own machine.
-Right click on the root path you need to access
-Choose Properties
-Click on Share button and add your chosen users who can access it
This will then create a shared directory like \\{PCName}\{YourSharedRootDirectory} This could be definitely much less than your full path I hope, for me I could reduce to 30 characters from about 290 characters. :)
Upvotes: 0
Reputation: 572
The best answer I can find, is in one of the comments here. Adding it to the answer so that someone won't miss the comment and should definitely try this out. It fixed the issue for me.
We need to map the solution folder to a drive using the "subst" command in command prompt- e.g., subst z:
And then open the solution from this drive (z in this case). This would shorten the path as much as possible and could solve the lengthy filename issue.
Upvotes: 0
Reputation: 839
Not mention so far and an update, there is a very well establish library for handling paths that are too long. AlphaFS is a .NET library providing more complete Win32 file system functionality to the .NET platform than the standard System.IO classes. The most notable deficiency of the standard .NET System.IO is the lack of support of advanced NTFS features, most notably extended length path support (eg. file/directory paths longer than 260 characters).
Upvotes: 2
Reputation: 517
What worked for me is moving my project as it was on the desktop (C:\Users\lachezar.l\Desktop\MyFolder) to (C:\0\MyFolder) which as you can see uses shorter path and reducing it solved the problem.
Upvotes: 6
Reputation: 6943
If you are having an issue with your bin files due to a long path, In Visual Studio 2015 you can go to the offending project's property page and change the relative Output Directory to a shorter one.
E.g. bin\debug\ becomes C:\_bins\MyProject\
Upvotes: 2
Reputation: 1107
You can create a symbolic link with a shorter directory.
First open command line for example by Shift + RightClick
in your desired folder with a shorter path (you may have to run it as administrator).
Then type with relative or absolute paths:
mklink ShortPath\To\YourLinkedSolution C:\Path\To\Your\Solution /D
And then start the Solution from the shorter path. The advantage here is: You don't have to move anything.
Upvotes: 9
Reputation: 61862
As the cause of the error is obvious, here's some information that should help you solve the problem:
See this MS article about Naming Files, Paths, and Namespaces
Here's a quote from the link:
Maximum Path Length Limitation In the Windows API (with some exceptions discussed in the following paragraphs), the maximum length for a path is MAX_PATH, which is defined as 260 characters. A local path is structured in the following order: drive letter, colon, backslash, name components separated by backslashes, and a terminating null character. For example, the maximum path on drive D is "D:\some 256-character path string<NUL>" where "<NUL>" represents the invisible terminating null character for the current system codepage. (The characters < > are used here for visual clarity and cannot be part of a valid path string.)
And a few workarounds (taken from the comments):
There are ways to solve the various problems. The basic idea of the solutions listed below is always the same: Reduce the path-length in order to have path-length + name-length < MAX_PATH
. You may:
Upvotes: 70
Reputation: 3445
There's a library called Zeta Long Paths that provides a .NET API to work with long paths.
Here's a good article that covers this issue for both .NET and PowerShell: ".NET, PowerShell Path too Long Exception and a .NET PowerShell Robocopy Clone"
Upvotes: 27
Reputation: 168
On Windows 8.1, using. NET 3.5, I had a similar problem.
Although the name of my file was only 239 characters length when I went to instantiate a FileInfo object with just the file name (without path) occurred an exception of type System. IO.PathTooLongException
2014-01-22 11:10:35 DEBUG LogicalDOCOutlookAddIn.LogicalDOCAddIn - fileName.Length: 239
2014-01-22 11:10:35 ERROR LogicalDOCOutlookAddIn.LogicalDOCAddIn - Exception in ImportEmail System.IO.PathTooLongException: Percorso e/o nome di file specificato troppo lungo. Il nome di file completo deve contenere meno di 260 caratteri, mentre il nome di directory deve contenere meno di 248 caratteri.
in System.IO.Path.NormalizePathFast(String path, Boolean fullCheck)
in System.IO.FileInfo..ctor(String fileName)
in LogicalDOCOutlookAddIn.LogicalDOCAddIn.GetTempFilePath(String fileName) in C:\Users\alle\Documents\Visual Studio 2010\Projects\MyAddin1Outlook20072010\MyAddin1Outlook20072010\LogicalDOCAddIn.cs:riga 692
in LogicalDOCOutlookAddIn.LogicalDOCAddIn.ImportEmail(_MailItem mailItem, OutlookConfigXML configXML, Int64 targetFolderID, String SID) in C:\Users\alle\Documents\Visual Studio 2010\Projects\MyAddin1Outlook20072010\MyAddin1Outlook20072010\LogicalDOCAddIn.cs:riga 857
in LogicalDOCOutlookAddIn.LogicalDOCAddIn.ImportEmails(Explorers explorers, OutlookConfigXML configXML, Int64 targetFolderID, Boolean suppressResultMB) in C:\Users\alle\Documents\Visual Studio 2010\Projects\MyAddin1Outlook20072010\MyAddin1Outlook20072010\LogicalDOCAddIn.cs:riga 99
I resolved the problem trimming the file name to 204 characters (extension included).
Upvotes: 2